A UI Razor component that shows temporary full-screen flash messages. It stores a single active flash class, text and expiry time, exposes static Instance, provides Flash(...) and several convenience methods (BossSpawn, WaveStart, etc.), and clears the flash after its duration in OnUpdate.
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@namespace Sandbox
<root>
@if (!string.IsNullOrEmpty(_flashClass))
{
<div class="screen-flash @_flashClass">
@if (!string.IsNullOrEmpty(_flashText))
{
<div class="flash-text">@_flashText</div>
}
</div>
}
</root>
@code {
public static ScreenFlash Instance { get; private set; }
string _flashClass = "";
string _flashText = "";
float _flashEndsAt = 0f;
protected override void OnStart()
{
Instance = this;
}
protected override void OnUpdate()
{
if (!string.IsNullOrEmpty(_flashClass))
{
if (Time.Now >= _flashEndsAt)
{
Log.Info($"Flash clearing: was {_flashClass}");
_flashClass = "";
_flashText = "";
StateHasChanged();
}
else
{
// Keep component updated while flash is active
//StateHasChanged();
}
}
}
// Generic flash — pass any css class
public void Flash(string cssClass, float duration, string text = "")
{
Log.Info($"Flash called: {cssClass} for {duration}s, text='{text}'");
_flashClass = cssClass;
_flashText = text;
_flashEndsAt = Time.Now + duration;
StateHasChanged();
}
// Convenience shorthands public void BossSpawn() => Flash("flash-boss-spawn", 0.8f);
public void BossSpawn() => Flash("flash-boss-spawn", 0.8f, $"Boss has spawned!");
public void BossDeath() => Flash("flash-boss-death", 0.6f);
public void WaveStart(int wave) => Flash("flash-wave-start", 1.0f, $"WAVE {wave}");
public void NewBest() => Flash("flash-new-best", 1.0f, "🏆 NEW BEST!");
public void GameOver() => Flash("flash-game-over", 0.8f);
protected override int BuildHash() =>
System.HashCode.Combine(_flashClass, _flashText, _flashEndsAt);
}