add color to server
This commit is contained in:
parent
2caf0d4d91
commit
d337c0507d
5 changed files with 118 additions and 24 deletions
17
client/UserUtils.cs
Normal file
17
client/UserUtils.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
using Godot;
|
||||||
|
using SpacetimeDB.Types;
|
||||||
|
|
||||||
|
public static class UserUtils
|
||||||
|
{
|
||||||
|
public static Color ParseColor(User user)
|
||||||
|
{
|
||||||
|
return user.Color != null && Color.HtmlIsValid(user.Color)
|
||||||
|
? Color.FromHtml(user.Color)
|
||||||
|
: Colors.AliceBlue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string UserNameOrIdentity(User user)
|
||||||
|
{
|
||||||
|
return user != null ? user.Name ?? user.Identity.ToString()[..8] : "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
1
client/UserUtils.cs.uid
Normal file
1
client/UserUtils.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dnaxnse8ipje0
|
||||||
|
|
@ -4,7 +4,7 @@ using SpacetimeDB.Types;
|
||||||
|
|
||||||
public partial class ChatLog : RichTextLabel
|
public partial class ChatLog : RichTextLabel
|
||||||
{
|
{
|
||||||
const string SystemColor = "#747474";
|
private static readonly Color SystemColor = Colors.Gray;
|
||||||
|
|
||||||
public override void _EnterTree()
|
public override void _EnterTree()
|
||||||
{
|
{
|
||||||
|
|
@ -17,14 +17,9 @@ public partial class ChatLog : RichTextLabel
|
||||||
RegisterSubscriptions(conn);
|
RegisterSubscriptions(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
string UserNameOrIdentity(User user)
|
void PushMessage(string name, string message, Color color)
|
||||||
{
|
{
|
||||||
return user != null ? user.Name ?? user.Identity.ToString()[..8] : "unknown";
|
string entry = $"[color={color.ToHtml()}]{name}:[/color] {message}";
|
||||||
}
|
|
||||||
|
|
||||||
void PushMessage(string name, string message, string color)
|
|
||||||
{
|
|
||||||
string entry = $"[color={color}]{name}:[/color] {message}";
|
|
||||||
this.Text += $"{entry}\n";
|
this.Text += $"{entry}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +42,11 @@ public partial class ChatLog : RichTextLabel
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PushMessage("System", $"{UserNameOrIdentity(insertedValue)} connected", SystemColor);
|
PushMessage(
|
||||||
|
"System",
|
||||||
|
$"{UserUtils.UserNameOrIdentity(insertedValue)} connected",
|
||||||
|
SystemColor
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void User_OnUpdate(EventContext ctx, User oldValue, User newValue)
|
void User_OnUpdate(EventContext ctx, User oldValue, User newValue)
|
||||||
|
|
@ -56,7 +55,7 @@ public partial class ChatLog : RichTextLabel
|
||||||
{
|
{
|
||||||
PushMessage(
|
PushMessage(
|
||||||
"System",
|
"System",
|
||||||
$"{UserNameOrIdentity(oldValue)} renamed to {UserNameOrIdentity(newValue)}",
|
$"{UserUtils.UserNameOrIdentity(oldValue)} renamed to {UserUtils.UserNameOrIdentity(newValue)}",
|
||||||
SystemColor
|
SystemColor
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -64,11 +63,19 @@ public partial class ChatLog : RichTextLabel
|
||||||
{
|
{
|
||||||
if (newValue.Online)
|
if (newValue.Online)
|
||||||
{
|
{
|
||||||
PushMessage("System", $"{UserNameOrIdentity(newValue)} connected", SystemColor);
|
PushMessage(
|
||||||
|
"System",
|
||||||
|
$"{UserUtils.UserNameOrIdentity(newValue)} connected",
|
||||||
|
SystemColor
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PushMessage("System", $"{UserNameOrIdentity(newValue)} disconnected", SystemColor);
|
PushMessage(
|
||||||
|
"System",
|
||||||
|
$"{UserUtils.UserNameOrIdentity(newValue)} disconnected",
|
||||||
|
SystemColor
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -76,12 +83,12 @@ public partial class ChatLog : RichTextLabel
|
||||||
void Message_OnInsert(EventContext ctx, Message insertedValue)
|
void Message_OnInsert(EventContext ctx, Message insertedValue)
|
||||||
{
|
{
|
||||||
User sender = ctx.Db.User.Identity.Find(insertedValue.Sender);
|
User sender = ctx.Db.User.Identity.Find(insertedValue.Sender);
|
||||||
string color = sender.Identity.Equals(Spacetime.Instance.Identity) ? "blue" : "red";
|
Color color = ctx.Identity == sender.Identity ? UserUtils.ParseColor(sender) : Colors.Red;
|
||||||
if (ctx.Event is Event<Reducer>.SubscribeApplied)
|
if (ctx.Event is Event<Reducer>.SubscribeApplied)
|
||||||
{
|
{
|
||||||
PushMessage(UserNameOrIdentity(sender), insertedValue.Text, color);
|
PushMessage(UserUtils.UserNameOrIdentity(sender), insertedValue.Text, color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PushMessage(UserNameOrIdentity(sender), insertedValue.Text, color);
|
PushMessage(UserUtils.UserNameOrIdentity(sender), insertedValue.Text, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ public partial class ChatOptions : HBoxContainer
|
||||||
Username = GetNode<LineEdit>("Username");
|
Username = GetNode<LineEdit>("Username");
|
||||||
ColorPicker = GetNode<ColorPickerButton>("ColorPicker");
|
ColorPicker = GetNode<ColorPickerButton>("ColorPicker");
|
||||||
|
|
||||||
Username.TextSubmitted += OnUsernameInput;
|
Username.TextSubmitted += OnUsernameChanged;
|
||||||
Username.FocusExited += ResetUsername;
|
Username.FocusExited += ResetUsername;
|
||||||
|
|
||||||
|
ColorPicker.ColorChanged += OnColorChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
|
|
@ -22,24 +24,52 @@ public partial class ChatOptions : HBoxContainer
|
||||||
RegisterSubscriptions(conn);
|
RegisterSubscriptions(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
string UserNameOrIdentity(User user)
|
|
||||||
{
|
|
||||||
return user != null ? user.Name ?? user.Identity.ToString()[..8] : "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetUsername()
|
void ResetUsername()
|
||||||
{
|
{
|
||||||
Username.Text = UserNameOrIdentity(Spacetime.Instance.Me);
|
Username.Text = UserUtils.UserNameOrIdentity(Spacetime.Instance.Me);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnUsernameInput(string text)
|
void OnUsernameChanged(string text)
|
||||||
{
|
{
|
||||||
Spacetime.Instance.Connection.Reducers.SetName(text);
|
Spacetime.Instance.Connection.Reducers.SetName(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnColorChange(Color color)
|
||||||
|
{
|
||||||
|
Spacetime.Instance.Connection.Reducers.SetColor(color.ToHtml(false));
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterSubscriptions(DbConnection conn)
|
void RegisterSubscriptions(DbConnection conn)
|
||||||
{
|
{
|
||||||
|
conn.Db.User.OnInsert += User_OnInsert;
|
||||||
|
conn.Db.User.OnUpdate += User_OnUpdate;
|
||||||
conn.Reducers.OnSetName += Reducer_OnSetNameEvent;
|
conn.Reducers.OnSetName += Reducer_OnSetNameEvent;
|
||||||
|
conn.Reducers.OnSetColor += Reducer_OnSetColorEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void User_OnInsert(EventContext ctx, User insertedValue)
|
||||||
|
{
|
||||||
|
// It's me
|
||||||
|
if (ctx.Identity == insertedValue.Identity)
|
||||||
|
{
|
||||||
|
Username.Text = insertedValue.Name;
|
||||||
|
ColorPicker.Color =
|
||||||
|
insertedValue.Color != null && Color.HtmlIsValid(insertedValue.Color)
|
||||||
|
? Color.FromHtml(insertedValue.Color)
|
||||||
|
: Colors.AliceBlue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void User_OnUpdate(EventContext ctx, User oldValue, User newValue)
|
||||||
|
{
|
||||||
|
if (ctx.Identity == oldValue.Identity && ctx.Identity == newValue.Identity)
|
||||||
|
{
|
||||||
|
Username.Text = newValue.Name;
|
||||||
|
ColorPicker.Color =
|
||||||
|
newValue.Color != null && Color.HtmlIsValid(newValue.Color)
|
||||||
|
? Color.FromHtml(newValue.Color)
|
||||||
|
: Colors.AliceBlue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Our `OnSetNameEvent` callback: print a warning if the reducer failed.
|
/// Our `OnSetNameEvent` callback: print a warning if the reducer failed.
|
||||||
|
|
@ -57,4 +87,19 @@ public partial class ChatOptions : HBoxContainer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Reducer_OnSetColorEvent(ReducerEventContext ctx, string color)
|
||||||
|
{
|
||||||
|
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 color to {color}: {error}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using SpacetimeDB;
|
using SpacetimeDB;
|
||||||
|
|
||||||
public static partial class Module
|
public static partial class Module
|
||||||
|
|
@ -8,6 +9,7 @@ public static partial class Module
|
||||||
[PrimaryKey]
|
[PrimaryKey]
|
||||||
public Identity Identity;
|
public Identity Identity;
|
||||||
public string? Name;
|
public string? Name;
|
||||||
|
public string? Color;
|
||||||
public bool Online;
|
public bool Online;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,6 +44,29 @@ public static partial class Module
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Reducer]
|
||||||
|
public static void SetColor(ReducerContext ctx, string color)
|
||||||
|
{
|
||||||
|
color = ValidateColor(color);
|
||||||
|
|
||||||
|
var user = ctx.Db.User.Identity.Find(ctx.Sender);
|
||||||
|
if (user is not null)
|
||||||
|
{
|
||||||
|
user.Color = color;
|
||||||
|
ctx.Db.User.Identity.Update(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ValidateColor(string color)
|
||||||
|
{
|
||||||
|
var regex = new Regex("^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
|
||||||
|
if (!regex.IsMatch(color))
|
||||||
|
{
|
||||||
|
throw new Exception("Invalid color code");
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
[Reducer]
|
[Reducer]
|
||||||
public static void SendMessage(ReducerContext ctx, string text)
|
public static void SendMessage(ReducerContext ctx, string text)
|
||||||
{
|
{
|
||||||
|
|
@ -113,4 +138,3 @@ public static partial class Module
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue