Luski/Luski/GUI/MainScreen/UI/ChatMessage.cs
JacobTech bdb1e350f6 Upkeeping
This push is just to prevent a merge conflict for myself.
2023-07-03 23:26:16 -04:00

202 lines
7.9 KiB
C#

using System.Reflection;
using GraphicsManager;
using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
using GraphicsManager.Objects;
using GraphicsManager.Objects.Core;
using Luski.net;
using Luski.net.Enums;
using Luski.net.Interfaces;
using Luski.net.JsonTypes;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
namespace Luski.GUI.MainScreen.UI;
public class ChatMessage : UserControl
{
readonly int padding = 2;
private static Font TimeFont = Font.MakeFontFromSystem(13);
private SocketMessage Msg { get; }
private Label label2, lastm;
private static Dictionary<SocketRemoteUser, ContextMenu> Menues = new();
private static Dictionary<SocketRemoteUser, List<ChatMessage>> Messages = new();
public ChatMessage(TextureManager tm, SocketMessage message)
{
Label label1;
Size = new((int)(723.5 * Globals.Settings.Scale), (int)(37 * Globals.Settings.Scale));
BackgroundColor = new(40, 40, 40, 255);
Msg = message;
IUser user = message.GetAuthor(CancellationToken.None).Result;
Anchor = ObjectAnchor.Left | ObjectAnchor.Right;
Controls.Add(label1 = new Label() { Font = Globals.DefaultFont, Location = new((int)(54 * Globals.Settings.Scale), (int)(6 * Globals.Settings.Scale)), Text = user.Username});
DateTime time = new DateTime(2022, 1, 1, 0, 0, 0, 0).AddMilliseconds(Msg.Id >> 22).ToLocalTime();
string timestr;
if (time.Date == DateTime.Now.ToLocalTime().Date)
{
timestr = $"Today at {time.ToShortTimeString()}";
}
else if (time.Date == DateTime.Now.ToLocalTime().AddDays(-1).Date)
{
timestr = $"Yesterday at {time.ToShortTimeString()}";
}
else
{
timestr = $"{time:M/dd/yyyy h:mm tt}";
}
Controls.Add(new Label() { Scale = 0.8f, Font = Globals.DefaultFont, Location = new(label1.Location.X + label1.Size.X + 4, label1.Location.Y), Text = timestr});
Rectangle r = new Rectangle(tm.AddTexture(Tools.GetResourceBytes(Assembly.GetExecutingAssembly(),
"Luski.Resources.Textures.Status.png"))) { Location = new((int)(10 * Globals.Settings.Scale), (int)(2 * Globals.Settings.Scale)), Size = new((int)(38 * Globals.Settings.Scale)) };
Texture tex = tm.AddTexture(user.GetAvatar(CancellationToken.None, Globals.Luski.CurrentUser.Servers.First()).Result);
tex.Unit = TextureUnit.Texture1;
r.Shader = Rectangle.DefaultAlphaTextureShader[Globals.ms.Context];
r.Textures.Add(tex);
Controls.Add(r);
Controls.Add(label2 = new Label() { Font = Globals.DefaultFont, Location = new(label1.Location.X, (int)(label1.Location.Y + label1.Font.PixelHeight + (5 * Globals.Settings.Scale))), Text = message.Context});
lastm = label2;
if (Msg.Files != null && Msg.Files.Length > 0)
{
int row = 1;
int filesonrow = 0;
for (int i = 0; i < Msg.Files.Length; i++)
{
int lx = (padding * filesonrow) + lastm.Location.X + (333 * (filesonrow + 1));
if (lx > Size.X)
{
row++;
filesonrow = 0;
lx = (padding * filesonrow) + lastm.Location.X + (333 * (filesonrow + 1));
}
filesonrow++;
Controls.Add(new ContentEmbed(Msg.Files[i], Msg.ChannelID)
{
Location = new(lx - 333, lastm.Location.Y + 2 + lastm.Size.Y +(padding * row) + (66 * (row - 1)))
});
}
}
if (user is SocketRemoteUser u && u.FriendStatus == FriendStatus.NotFriends)
{
Tag = u;
if (!Menues.ContainsKey(u))
{
ContextMenu m = new((int)(150 * Globals.Settings.Scale));
RoundedButton d;
m.Items.Add(d = new RoundedButton()
{
InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan,
Size = new((int)(25 * Globals.Settings.Scale)), Font = Globals.DefaultFont, Text = "Add Friend"
});
d.Tag = this;
Menues.Add(u,m);
Messages.Add(u, new());
d.Clicked += DOnClicked;
}
Messages[u].Add(this);
this.ContextMenu = Menues[u];
}
Size = new(Size.X, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y + padding + 10);
}
private Task DOnClicked(IRenderObject arg)
{
if (arg.Tag is ChatMessage u && u.Tag is SocketRemoteUser uu)
{
foreach (ChatMessage cm in Messages[uu])
{
cm.ContextMenu!.IsVisible = false;
cm.ContextMenu!.Close();
cm.ContextMenu = null;
}
Messages.Remove(uu);
Menues.Remove(uu);
SocketRemoteUser result = Globals.Luski
.SendFriendRequest(long.Parse(uu.friend_codes.First()), CancellationToken.None).Result;
if (result.Channel is null)
Globals.ms.AddFriendRequest(result);
else
Globals.ms.AddFriend(result);
}
return Task.CompletedTask;
}
public void AddMessage(SocketMessage msg)
{
Label newLabel = new()
{
Font = Globals.DefaultFont,
Text = msg.Context,
Tag = msg,
Location = new(label2.Location.X, Size.Y)
};
newLabel.MouseEnter += NewLabel_MouseEnter;
newLabel.MouseLeave += NewLabel_MouseLeave;
Controls.Add(newLabel);
if (msg.Files is not null && msg.Files.Length > 0)
{
int row = 1;
int filesonrow = 0;
for (int i = 0; i < msg.Files.Length; i++)
{
int lx = (padding * filesonrow) + lastm.Location.X + (333 * (filesonrow + 1));
if (lx > Size.X)
{
row++;
filesonrow = 0;
lx = (padding * filesonrow) + lastm.Location.X + (333 * (filesonrow + 1));
}
filesonrow++;
Controls.Add(new ContentEmbed(msg.Files[i], Msg.ChannelID)
{
Location = new(lx - 333, lastm.Location.Y + 2 + lastm.Size.Y +(padding * row) + (66 * (row - 1)))
});
}
}
Size = new(Size.X, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y + padding + 10);
}
readonly List<Label> Labels = new();
private Task NewLabel_MouseLeave(IRenderObject sender)
{
if (sender is not Label label) return Task.CompletedTask;
if (label.Tag is not SocketMessage Message) return Task.CompletedTask;
DateTime time = new DateTime(2022, 1, 1, 0, 0, 0, 0).AddMilliseconds(Message.Id >> 22).ToLocalTime();
string b = time.ToString("h:mm tt");
Label[] l = Labels.Where(s => s.Text == b).ToArray();
if (l.Any())
{
Controls.Remove(l.First());
Labels.Remove(l.First());
}
Window!.DrawFrame();
return Task.CompletedTask;
}
private Task NewLabel_MouseEnter(IRenderObject sender)
{
if (sender is not Label label) return Task.CompletedTask;
if (label.Tag is not SocketMessage Message) return Task.CompletedTask;
DateTime time = new DateTime(2022, 1, 1, 0, 0, 0, 0).AddMilliseconds(Message.Id >> 22).ToLocalTime();
Label m = new()
{
Font = TimeFont,
Text = time.ToString("h:mm tt"),
Location = new((int)(7.5 * Globals.Settings.Scale), label.Location.Y - (int)TimeFont.PixelHeight + (int)label.Font.PixelHeight),
};
Controls.Add(m);
Labels.Add(m);
Window!.DrawFrame();
return Task.CompletedTask;
}
}