A Razor UI panel that displays a leaderboard of tallest trees. It renders a sheet with header, loading/status note, a list of leaderboard rows (rank, name, height) with special classes for top ranks and the local player, and provides refresh and close actions.
@using System
@using Sandbox
@using Sandbox.UI
@namespace DesertPump
@inherits Panel
<root class="treepanel">
<div class="scrim" onclick="@Close"></div>
<div class="sheet">
<div class="head">
<div class="title"><i>emoji_events</i> TALLEST TREES</div>
<div class="closebtn" onclick="@Close"><i>close</i></div>
</div>
@if ( Leaderboard.Fetching )
{
<div class="note">Loading the board...</div>
}
else if ( !string.IsNullOrEmpty( Leaderboard.Status ) )
{
<div class="note">@Leaderboard.Status</div>
}
<div class="rows">
@foreach ( var row in Leaderboard.Entries )
{
<div class="lbrow @( row.IsMe ? "me" : "" ) @RankClass( row.Rank )">
<div class="rank">@row.Rank</div>
<div class="who">@row.Name</div>
<div class="score"><span class="num">@row.Height</span><span class="unit">stages</span></div>
</div>
}
</div>
<div class="refresh" onclick="@Reload">
<i>refresh</i> REFRESH
</div>
</div>
</root>
@code
{
public Action OnClose { get; set; }
static DesertPumpGame Game => DesertPumpGame.Current;
protected override void OnAfterTreeRender( bool firstTime )
{
base.OnAfterTreeRender( firstTime );
if ( firstTime ) Reload();
}
void Reload()
{
var name = Connection.Local?.DisplayName;
if ( string.IsNullOrWhiteSpace( name ) ) name = "You";
_ = Leaderboard.Refresh( Game?.TreeHeight ?? 0, name );
StateHasChanged();
}
static string RankClass( int rank ) => rank switch
{
1 => "gold",
2 => "silver",
3 => "bronze",
_ => string.Empty
};
void Close() => OnClose?.Invoke();
protected override int BuildHash() => HashCode.Combine(
Leaderboard.Entries.Count, Leaderboard.Fetching, Leaderboard.Status, Game?.TreeHeight ?? 0 );
}