2024-04-01 10:12:49 -04:00

223 lines
8.5 KiB
C#

using System.Diagnostics;
using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
using GraphicsManager.Objects;
using Luski.net.Interfaces;
using Luski.net.Structures.Main;
using Luski.net.Structures.Public;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common.Input;
using Label = GraphicsManager.Objects.Label;
namespace Luski.GUI.MainScreen.UI.PublicServers;
public class ChatMessage : UserControl
{
private SocketMessage Msg { get; }
private SocketChannel ch { get; }
public PublicChat pc;
private IRenderObject LastObject;
private Label FirstL;
private readonly double HorPadding = 12.ScaleDouble(),
VerticalPadding = 0.ScaleDouble();
private static Dictionary<MainSocketRemoteUser, List<ChatMessage>> Messages = new();
public static async Task<ChatMessage> MakeChatMessage(PublicChat p, SocketMessage message)
{
IUser auth = await message.GetAuthor(CancellationToken.None);
Color c = await auth.GetColor();
Color4 c4 = new(c.R, c.G, c.B, c.A);
return new ChatMessage(p, message, await message.GetParent(CancellationToken.None), auth, await auth.MakeRct(new(40.ScaleInt()), message.IsProfile), c4);
}
private ChatMessage(PublicChat p, SocketMessage message, SocketChannel chan, IUser Author, IRenderObject UserIcon, Color4 UserNameColor)
{
pc = p;
Label label1;
base.Size = new(723.5.ScaleInt(), 37.ScaleInt());
ch = chan;
base.BackgroundColor = new(40, 40, 40, 255);
Msg = message;
Anchor = ObjectAnchor.Left | ObjectAnchor.Right;
DateTime time = chan.Epoch.AddMilliseconds(Msg.ID >> 20).ToLocalTime();
string time_str;
if (time.Date == DateTime.Now.ToLocalTime().Date)
{
time_str = $"Today at {time.ToShortTimeString()}";
}
else if (time.Date == DateTime.Now.ToLocalTime().AddDays(-1).Date)
{
time_str = $"Yesterday at {time.ToShortTimeString()}";
}
else
{
time_str = $"{time:M/dd/yyyy h:mm tt}";
}
UserIcon.Location = new(10.ScaleInt(), 2.ScaleInt(), 0);
Controls.Add(UserIcon);
Controls.Add(label1 = new Label(Globals.DefaultFont) { Color = UserNameColor, Text = Author.DisplayName });
label1.Location = new(
54.ScaleInt(),
//(int)(UserIcon.Location.Y + (UserIcon.Size.Y / 2) - (label1.Font.CurrentFonts[0].Face.Size.Metrics.NominalHeight / 2) - label1.Size.Y + label1.Font.PixelHeight),
UserIcon.Location.Y,
0);
LastObject = label1;
FirstL = label1;
Controls.Add(new Label(Globals.TopTimeFont) { Location = new(label1.Location.X + label1.Size.X + 8.ScaleInt(), (int)(label1.Location.Y + label1.Font.PixelHeight - Globals.TopTimeFont.PixelHeight), 0), Text = time_str});
if (!string.IsNullOrWhiteSpace(Msg.Context))
{
Label l;
Controls.Add(l = new Label(Globals.MessageFont) { Location = new(LastObject.Location.X, (int)(UserIcon.Location.Y + UserIcon.Size.Y - Globals.MessageFont.PixelHeight), 0), Text = message.Context});
LastObject = l;
}
if (Msg.Files.Count > 0)
{
int row = 1;
int files_on_row = 0;
for (int i = 0; i < Msg.Files.Count; i++)
{
double lx = (HorPadding * files_on_row) + LastObject.Location.X + (333 * (files_on_row + 1));
if (lx > base.Size.X)
{
row++;
files_on_row = 0;
lx = (HorPadding * files_on_row) + LastObject.Location.X + (333 * (files_on_row + 1));
}
files_on_row++;
IRenderObject cem = ContentEmbed.GetEmbed(this, Msg.Files[i], Msg.ChannelID).Result;
cem.Location = new((int)(lx - 333), (int)(LastObject.Location.Y + 2 + LastObject.Size.Y + (HorPadding * row) + (66 * (row - 1))), 0);
LastObject = cem;
Controls.Add(cem);
}
}
if (LastObject is Label ll) base.Size = new(base.Size.X, (int)(ll.Location.Y + ll.Size.Y + VerticalPadding));
else base.Size = new(base.Size.X ,(int)(LastObject.Location.Y + LastObject.Size.Y + VerticalPadding));
}
public async Task AddMessage(SocketMessage msg)
{
BlockDraw = true;
Label newLabel;
if (!string.IsNullOrWhiteSpace(msg.Context))
{
newLabel = new(Globals.MessageFont)
{
Text = msg.Context,
Tag = msg
};
if (LastObject is Label l)
{
newLabel.Location = new(FirstL.Location.X, (int)(l.Location.Y + l.Size.Y + VerticalPadding), 0);
}
else
{
newLabel.Location = new(FirstL.Location.X, Size.Y, 0);
}
bool result = Uri.TryCreate(newLabel.Text, UriKind.Absolute, out Uri? uriResult)
&& (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
if (result)
{
newLabel.HoverMouse = MouseCursor.Hand;
newLabel.Color = Color4.Aqua;
newLabel.Clicked += NewLabelOnClicked;
}
newLabel.MouseEnter += NewLabel_MouseEnter;
newLabel.MouseLeave += NewLabel_MouseLeave;
Controls.Add(newLabel);
LastObject = newLabel;
}
if (msg.Files.Count > 0)
{
int row = 1;
int filesonrow = 0;
for (int i = 0; i < msg.Files.Count; i++)
{
double lx = (HorPadding * filesonrow) + LastObject.Location.X + (333 * (filesonrow + 1));
if (lx > Size.X)
{
row++;
filesonrow = 0;
lx = (HorPadding * filesonrow) + LastObject.Location.X + (333 * (filesonrow + 1));
}
filesonrow++;
IRenderObject cem = await ContentEmbed.GetEmbed(this, msg.Files[i], msg.ChannelID);
cem.Location = new((int)(lx - 333), (int)(LastObject.Location.Y + 2 + LastObject.Size.Y + (HorPadding * row) + (66 * (row - 1))), 0);
LastObject = cem;
Controls.Add(cem);
}
}
if (LastObject is Label ll) Size = new(Size.X, (int)(ll.Location.Y + ll.Size.Y + VerticalPadding));
else Size = new(Size.X ,(int)(LastObject.Location.Y + LastObject.Size.Y + VerticalPadding));
BlockDraw = false;
//if (Parent is not null) Globals.ms.pc.MessageFlow.ReportSizeUpdate(this);
TryDraw();
}
private Task NewLabelOnClicked(IRenderObject arg)
{
try
{
Label m = (arg as Label)!;
if (OperatingSystem.IsWindows())
Process.Start(m.Text);
else if (OperatingSystem.IsLinux())
{
if (m.Tag is string s) Process.Start("xdg-open", s);
else Process.Start("xdg-open", m.Text);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
return Task.CompletedTask;
}
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 MainSocketMessage 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!.TryDraw();
return Task.CompletedTask;
}
private Task NewLabel_MouseEnter(IRenderObject sender)
{
if (sender is not Label label) return Task.CompletedTask;
if (label.Tag is not MainSocketMessage Message) return Task.CompletedTask;
DateTime time = new DateTime(2022, 1, 1, 0, 0, 0, 0).AddMilliseconds(Message.Id >> 22).ToLocalTime();
Label m = new(Globals.DefaultFont)
{
Text = time.ToString("h:mm tt"),
Location = new(7.5.ScaleInt(), label.Location.Y - 13 + (int)label.Font.PixelHeight, 0),
};
Controls.Add(m);
Labels.Add(m);
Window!.TryDraw();
return Task.CompletedTask;
}
}