UI/ChatBox.razor
@using Sandbox;
@using Sandbox.UI;
@using System;
@using TikTokTTS;
@attribute [Icon("chat")]
@implements Component.INetworkListener
@inherits PanelComponent
<root>
<label style="font-weight: 700">Voice: @Player.Local?.Speech.VoiceName</label>
<label>Q/R to go Forward/Backward</label>
<TextEntry @ref="InputBox" class="chat-box" @onsubmit=@ChatFinished/>
</root>
@code
{
public TextEntry InputBox { get; set; }
private TimeSince TimeSinceChatted { get; set; } = 0;
protected override void OnUpdate()
{
base.OnUpdate();
if (InputBox is null)
return;
if (!Player.Local.IsValid())
return;
if (string.IsNullOrEmpty(InputBox.Text))
{
InputBox.Placeholder = "Press enter to chat";
} else if (TimeSinceChatted <= 4 && string.IsNullOrEmpty(InputBox.Text))
{
InputBox.Placeholder = $"Please wait {TimeSinceChatted.Relative.CeilToInt()} seconds";
}
if (Input.Pressed("chat"))
{
InputBox.Focus();
}
if (Input.Pressed("Menu"))
{
CycleVoice(-1);
}
if (Input.Pressed("Reload"))
{
CycleVoice(1);
}
}
private void CycleVoice(int offset)
{
TikTokSpeech speech = Player.Local?.Speech;
if (!speech.IsValid())
return;
TikTokVoice[] tikTokVoices = Enum.GetValues<TikTokVoice>();
int currentIndex = Array.IndexOf(tikTokVoices, speech.Voice);
int nextIndex = (currentIndex + offset + tikTokVoices.Length) % tikTokVoices.Length;
speech.Voice = tikTokVoices[nextIndex];
}
private void ChatFinished()
{
string text = InputBox.Text.Trim();
InputBox.Text = "";
if (string.IsNullOrWhiteSpace(text)) return;
Player.Local?.Speech.Speak(text.Normalize(), Player.Local?.Speech?.VoiceName);
}
/// <summary>
/// the hash determines if the system should be rebuilt. If it changes, it will be rebuilt
/// </summary>
protected override int BuildHash() => System.HashCode.Combine(Time.Now);
}