UI/Components/Chat.razor
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@implements Component.INetworkListener
<root>
<div class="output">
@foreach (var entry in Entries)
{
<div class="chat_entry">
<div class="author">@entry.author</div>
<div class="message">@entry.message</div>
</div>
}
</div>
<div class="input">
<TextEntry @ref="InputBox" onsubmit="@ChatFinished"></TextEntry>
</div>
</root>
@code
{
TextEntry InputBox;
public record Entry(string author, string message, RealTimeSince timeSinceAdded);
List<Entry> Entries = new();
protected override void OnUpdate()
{
if (EscapeMenu.isOpen)
return;
if (!InputBox.IsValid())
return;
Panel.AcceptsFocus = false;
if (Input.Pressed("chat"))
{
InputBox.Focus();
}
if (Entries.RemoveAll(x => x.timeSinceAdded > 30.0f) > 0)
{
StateHasChanged();
}
SetClass("open", InputBox.HasFocus);
}
void ChatFinished()
{
var text = InputBox.Text;
InputBox.Text = "";
if (string.IsNullOrWhiteSpace(text))
return;
AddText(Sandbox.Utility.Steam.PersonaName, text);
}
[Rpc.Broadcast]
public void AddText(string author, string message)
{
message = message.Truncate(300);
if (string.IsNullOrWhiteSpace(message))
return;
Log.Info($"{author}: {message}");
Entries.Add(new Entry(author, message, 0.0f));
StateHasChanged();
}
void Component.INetworkListener.OnConnected(Connection channel)
{
if (IsProxy) return;
AddText("🛎️", $"{channel.DisplayName} has joined the game");
}
void Component.INetworkListener.OnDisconnected(Connection channel)
{
if (IsProxy) return;
AddText("💨", $"{channel.DisplayName} has left the game");
}
}