@using System; @using Sandbox.UI; @namespace Sandbox @inherits PanelComponent @implements Component.INetworkListener @foreach (var entry in Entries) { @if (entry.steamid > 0) { } @entry.author @entry.message } @code { public static Chat Instance; public Chat() => Instance = this; public static bool IsActive => Instance.InputBox.HasFocus; public static void Open() { Instance.InputBox.Focus(); } public static void AddText(string text) { Instance.AddTextInternal(text); } public event Action OnChat; public TextEntry InputBox; public record Entry(ulong steamid, string author, string message, RealTimeSince timeSinceAdded); List Entries = new(); protected override void OnUpdate() { if (InputBox is null) return; Panel.AcceptsFocus = false; if (Input.Pressed("chat")) Open(); if (Entries.RemoveAll(x => x.timeSinceAdded > 20.0f) > 0) { StateHasChanged(); } if (InputBox.HasFocus && Input.EscapePressed) { Input.EscapePressed = false; ChatClosed(); } SetClass("open", InputBox.HasFocus); } void ChatFinished() { var text = InputBox.Text; Mouse.Visibility = MouseVisibility.Auto; OnChat?.Invoke(text); OnChat = null; if (string.IsNullOrWhiteSpace(text)) return; AddTextInternal(InputBox.Text); InputBox.Text = ""; } void ChatClosed() { var text = InputBox.Text; InputBox.Text = ""; OnChat = null; } [Rpc.Broadcast] public void AddTextInternal(string message) { message = message.Truncate(300); if (string.IsNullOrWhiteSpace(message)) return; var author = Rpc.Caller.DisplayName; var steamid = Rpc.Caller.SteamId; Log.Info($"{author}: {message}"); Entries.Add(new Entry(steamid, author, message, 0.0f)); StateHasChanged(); } [Rpc.Broadcast] void AddSystemText(string message) { message = message.Truncate(300); if (string.IsNullOrWhiteSpace(message)) return; Entries.Add(new Entry(0, "ℹ️", message, 0.0f)); StateHasChanged(); } void Component.INetworkListener.OnConnected(Connection channel) { if (IsProxy) return; AddSystemText($"{channel.DisplayName} has joined the game"); } void Component.INetworkListener.OnDisconnected(Connection channel) { if (IsProxy) return; AddSystemText($"{channel.DisplayName} has left the game"); } }