UI/Chat/Chatbox.razor
@using Sandbox.UI
@using Sandbox.Services
@using Sandbox.Audio
@using System
@attribute [Icon("message", "red", "white")]
@inherits PanelComponent
@namespace Donut.UI
<root>
<div class="chat_canvas">
@foreach (var entry in Entries)
{
<ChatEntry Entry=@entry />
}
</div>
<div class="input_canvas">
<TextEntry @ref="InputBox" placeholder="#chat.placeholder" onsubmit=@ChatFinished AllowEmojiReplace=@(true) />
</div>
</root>
@code
{
public static Chatbox Instance { get; private set; }
public record Entry(ulong SteamId, string Name, string Message, string Styles, RealTimeSince TimeSinceBorn);
private TextEntry InputBox;
private List<Entry> Entries = new();
protected override void OnAwake()
{
Instance = this;
}
protected override void OnUpdate()
{
if (InputBox is null) return;
Panel.AcceptsFocus = false;
if (Input.Pressed("Chat"))
{
InputBox.Focus();
Sound.Play("select").TargetMixer = Mixer.FindMixerByName("UI");
}
// todo: figure out a better way to prune entries
// and not tank performance, perhaps as a setting?
if (Entries.Count > 25)
{
Entries.RemoveAt(0);
StateHasChanged();
}
SetClass("open", InputBox.HasFocus);
}
void ChatFinished()
{
string text = InputBox.Text.Trim().Substring(0, Math.Min(InputBox.Text.Trim().Length, 1024));
string styles = "";
InputBox.Text = "";
if (string.IsNullOrWhiteSpace(text)) return;
if (ResourceLibrary.Get<GamePass>("data/donator.gamepass").Has())
styles += " rainbow";
AddMessage(Game.SteamId.ToString(), text, styles);
}
[Broadcast]
public void AddMessage(string sender, string message, string styles = "")
{
if (string.IsNullOrWhiteSpace(message)) return;
ulong steamId = 0;
string name = "";
if (ulong.TryParse(sender, out steamId))
{
var friend = new Friend((long)steamId);
name = friend.Name;
steamId = friend.Id;
}
else
{
name = sender;
}
Entries.Add(new Entry(steamId, name, message, styles, 0));
Sound.Play("talk").TargetMixer = Mixer.FindMixerByName("UI");
StateHasChanged();
}
public void AddLocalMessage(string sender, string message, string styles = "")
{
if (string.IsNullOrWhiteSpace(message)) return;
Entries.Add(new Entry(0, sender, message, styles, 0));
Sound.Play("talk").TargetMixer = Mixer.FindMixerByName("UI");
StateHasChanged();
}
}