223 lines
8.5 KiB
C#
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;
|
|
}
|
|
} |