136 lines
3.8 KiB
C#
136 lines
3.8 KiB
C#
using Godot;
|
|
using SpacetimeDB;
|
|
using SpacetimeDB.Types;
|
|
|
|
public partial class ChatWindow : VBoxContainer
|
|
{
|
|
const string SystemColor = "#747474";
|
|
|
|
private LineEdit _userNameInput;
|
|
private ChatLog _log;
|
|
private LineEdit _input;
|
|
|
|
// Called when the node enters the scene tree for the first time.
|
|
public override void _EnterTree()
|
|
{
|
|
_userNameInput = GetNode<LineEdit>("Options/Username");
|
|
_log = GetNode<ChatLog>("ChatLog");
|
|
_input = GetNode<LineEdit>("ChatInput");
|
|
|
|
_log.Text = "";
|
|
}
|
|
|
|
string UserNameOrIdentity(User user)
|
|
{
|
|
return user != null ? user.Name ?? user.Identity.ToString()[..8] : "unknown";
|
|
}
|
|
|
|
// Called when the node enters the scene tree for the first time.
|
|
public override void _Ready()
|
|
{
|
|
DbConnection conn = Spacetime.Instance.Connection;
|
|
|
|
_userNameInput.TextSubmitted += OnUsernameInput;
|
|
_userNameInput.FocusExited += ResetUsername;
|
|
_input.TextSubmitted += OnMessageInput;
|
|
|
|
conn.Db.User.OnInsert += User_OnInsert;
|
|
conn.Db.User.OnUpdate += User_OnUpdate;
|
|
|
|
conn.Db.Message.OnInsert += Message_OnInsert;
|
|
|
|
conn.Reducers.OnSetName += Reducer_OnSetNameEvent;
|
|
conn.Reducers.OnSendMessage += Reducer_OnSendMessageEvent;
|
|
}
|
|
|
|
void ResetUsername()
|
|
{
|
|
_userNameInput.Text = UserNameOrIdentity(Spacetime.Instance.Me);
|
|
}
|
|
|
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
public override void _Process(double delta)
|
|
{
|
|
}
|
|
|
|
private void OnUsernameInput(string text)
|
|
{
|
|
Spacetime.Instance.Connection.Reducers.SetName(text);
|
|
}
|
|
|
|
private void OnMessageInput(string text)
|
|
{
|
|
Spacetime.Instance.Connection.Reducers.SendMessage(text);
|
|
_input.Text = "";
|
|
}
|
|
|
|
void User_OnInsert(EventContext ctx, User insertedValue)
|
|
{
|
|
if (ctx.Event is Event<Reducer>.SubscribeApplied)
|
|
{
|
|
if (insertedValue.Identity == Spacetime.Instance.Identity)
|
|
{
|
|
ResetUsername();
|
|
}
|
|
return;
|
|
}
|
|
_log.PushMessage("System", $"{UserNameOrIdentity(insertedValue)} connected", SystemColor);
|
|
}
|
|
|
|
void User_OnUpdate(EventContext ctx, User oldValue, User newValue)
|
|
{
|
|
if (oldValue.Name != newValue.Name)
|
|
{
|
|
_log.PushMessage("System", $"{UserNameOrIdentity(oldValue)} renamed to {UserNameOrIdentity(newValue)}", SystemColor);
|
|
}
|
|
if (oldValue.Online != newValue.Online)
|
|
{
|
|
if (newValue.Online)
|
|
{
|
|
_log.PushMessage("System", $"{UserNameOrIdentity(newValue)} connected", SystemColor);
|
|
}
|
|
else
|
|
{
|
|
_log.PushMessage("System", $"{UserNameOrIdentity(newValue)} disconnected", SystemColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Message_OnInsert(EventContext ctx, Message insertedValue)
|
|
{
|
|
User sender = ctx.Db.User.Identity.Find(insertedValue.Sender);
|
|
string color = sender.Identity.Equals(Spacetime.Instance.Identity) ? "blue" : "red";
|
|
if (ctx.Event is Event<Reducer>.SubscribeApplied)
|
|
{
|
|
_log.PushMessage(UserNameOrIdentity(sender), insertedValue.Text, color);
|
|
return;
|
|
}
|
|
_log.PushMessage(UserNameOrIdentity(sender), insertedValue.Text, color);
|
|
}
|
|
|
|
/// Our `OnSetNameEvent` callback: print a warning if the reducer failed.
|
|
void Reducer_OnSetNameEvent(ReducerEventContext ctx, string name)
|
|
{
|
|
var e = ctx.Event;
|
|
if (e.CallerIdentity != Spacetime.Instance.Identity)
|
|
{
|
|
// Not me
|
|
return;
|
|
}
|
|
if (e.Status is Status.Failed(var error))
|
|
{
|
|
GD.PrintErr($"Failed to change name to {name}: {error}");
|
|
return;
|
|
}
|
|
}
|
|
|
|
/// Our `OnSendMessageEvent` callback: print a warning if the reducer failed.
|
|
void Reducer_OnSendMessageEvent(ReducerEventContext ctx, string text)
|
|
{
|
|
var e = ctx.Event;
|
|
if (e.CallerIdentity == Spacetime.Instance.Identity && e.Status is Status.Failed(var error))
|
|
{
|
|
GD.PrintErr($"Failed to send message {text}: {error}");
|
|
}
|
|
}
|
|
}
|