swb_hud/Chatbox.cs
using Sandbox.UI;
using Sandbox.UI.Construct;
using SWB.Player;
using SWB.Shared;
using System;
namespace SWB.HUD;
public class Chatbox : Panel
{
PlayerBase player;
Panel history;
TextEntry textEntry;
public Chatbox( PlayerBase player )
{
this.player = player;
StyleSheet.Load( "/swb_hud/Chatbox.cs.scss" );
var msgArea = Add.Panel( "msgArea" );
history = msgArea.Add.Panel( "history" );
textEntry = AddChild<TextEntry>();
textEntry.AddClass( "entry" );
textEntry.Placeholder = "Type here";
textEntry.AddEventListener( "onsubmit", () => Submit() );
textEntry.AcceptsFocus = true;
textEntry.AllowEmojiReplace = true;
textEntry.MaxLength = 60;
}
void Open()
{
AddClass( "open" );
textEntry.Focus();
AsyncScrollToBottom( 1 );
}
void Close()
{
RemoveClass( "open" );
}
void Submit()
{
Close();
var msg = textEntry.Text.Trim();
textEntry.Text = "";
if ( string.IsNullOrWhiteSpace( msg ) )
return;
Say( msg );
}
public void AddEntry( Guid senderId, string msg )
{
var senderGO = Game.ActiveScene.Directory.FindByGuid( senderId );
var sender = senderGO?.Components.Get<PlayerBase>();
if ( sender is null ) return;
var msgP = history.Add.Panel( "msgWrapper" );
msgP.Add.Label( sender.Network.Owner.DisplayName + ":", "name " + (!sender.IsProxy ? "self" : "") );
msgP.Add.Label( msg, "msg" );
AsyncMessageHide( msgP, 5000 );
AsyncScrollToBottom( 1 );
Log.Info( sender.Network.Owner.DisplayName + ": " + msg );
}
async void AsyncScrollToBottom( int delay )
{
await GameTask.Delay( delay );
history.TryScrollToBottom();
}
async void AsyncMessageHide( Panel msgWrapper, int delay )
{
await GameTask.Delay( delay );
msgWrapper?.AddClass( "fadeOut" );
await GameTask.Delay( 500 );
msgWrapper?.AddClass( "fadedOut" );
}
public override void Tick()
{
if ( Input.Pressed( InputButtonHelper.Chat ) )
Open();
}
[ConCmd( "say", Help = "Send a chat message" )]
public static void Say( string msg )
{
var player = PlayerBase.Local;
SendMsg( player.GameObject.Id, msg );
}
[Rpc.Broadcast]
public static void SendMsg( Guid senderId, string msg )
{
var player = PlayerBase.Local;
if ( player is null ) return;
var rootDisplay = player.RootDisplay as RootDisplay;
rootDisplay.AddChatEntry( senderId, msg );
}
}