UI/MapToast.razor

A Razor UI panel that shows a temporary map toast on screen. It displays the current map title and selected game mode, and auto-shows/hides based on a timer with an exit animation flag.

@using Machines.GameModes
@using Sandbox;
@using Sandbox.UI;
@using Machines.Components;
@using Machines.Resources;

@namespace Machines.UI
@inherits Panel

<root class="map-toast">
    @if ( Showing )
    {
        var flow = LobbyFlow.Current;
        <div class="toast-card @(Leaving ? "out" : "")">
            <span class="toast-title">@(BaseGameMode.Current?.Map?.Title ?? "")</span>
            <span class="toast-mode">@FormatMode( flow?.SelectedMode ?? default )</span>
        </div>
    }
</root>

@code
{
    /// <summary>
    /// Total time the toast is on screen (seconds).
    /// </summary>
    private const float Duration = 4f;

    /// <summary>
    /// Out-animation duration (must match the CSS transition).
    /// </summary>
    private const float OutTime = 0.45f;

    private float _startTime = -1f;

    private float Elapsed => _startTime < 0f ? -1f : Time.Now - _startTime;
    private bool Showing => _startTime >= 0f && Elapsed < Duration;
    private bool Leaving => Showing && Elapsed > Duration - OutTime;

    public override void Tick()
    {
        base.Tick();

        // Fire once on level load when the map is known.
        if ( _startTime < 0f && BaseGameMode.Current?.Map != null )
            _startTime = Time.Now;
    }

    private static string FormatMode( GameModeType mode ) => mode.ToString().ToUpper();

    protected override int BuildHash()
    {
        return System.HashCode.Combine(
            Showing,
            Leaving,
            BaseGameMode.Current?.Map,
            LobbyFlow.Current?.SelectedMode );
    }
}