diff --git a/Luski/GUI/MainScreen.cs b/Luski/GUI/MainScreen.cs index 396e526..be6dce7 100644 --- a/Luski/GUI/MainScreen.cs +++ b/Luski/GUI/MainScreen.cs @@ -9,6 +9,8 @@ using Luski.GUI.MainScreen.Interfaces; using Luski.GUI.MainScreen.UI; using Luski.GUI.StartPage.UI; using Luski.net; +using Luski.net.Enums; +using Luski.net.Interfaces; using Luski.net.JsonTypes; using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; @@ -28,12 +30,16 @@ public class MainScreen : Window Size = new OpenTK.Mathematics.Vector2i(481, 838), }; FlowLayout? channelpicker; + private RoundedButton? FriendManagerBtn; + private Chat? chat; public MainScreen() : base(Settings) { Login login; Controls.Add(login = new Login()); login.ChangeToApp += LoginOnChangeToApp; + Thread t = new(_ => Encryption.GenerateKeys()); + t.Start(); } public void AddGroup(SocketGroupChannel group) @@ -61,7 +67,13 @@ public class MainScreen : Window private Task ChannelOnClickCon(IChannelPick arg) { - //show their channel + chat!.UpdateTitle(arg); + chat.Clear(); + IReadOnlyList messages = arg.Channel.GetMessages(200).Result; + foreach (SocketMessage message in messages.Reverse()) + { + chat.AddMessage(message); + } return Task.CompletedTask; } @@ -72,16 +84,28 @@ public class MainScreen : Window Size = new(2048, 1334); WindowBorder = WindowBorder.Resizable; BackgroundColor = new Color4(34, 34, 34, 255); - Controls.Add(new Rectangle(new Texture(Globals.Luski.CurrentUser.GetAvatar().Result)) { Size = new(70, 70), Location = new(146, 78 + 1170)}); - Controls.Add(new Label(){Location = new(132 + 92, 39 + 62+1170), Text = Globals.Luski.CurrentUser.Username}); - + Controls.Add(new Rectangle(new Texture(Globals.Luski.CurrentUser.GetAvatar().Result)) { Anchor = ObjectAnchor.Bottom | ObjectAnchor.Left, Size = new(70, 70), Location = new(94, 1248)}); + Controls.Add(new Label(){ Anchor = ObjectAnchor.Bottom | ObjectAnchor.Left, Location = new(172, 1271), Text = Globals.Luski.CurrentUser.Username}); + FlowLayout ser; + Controls.Add(ser = new FlowLayout() + { + BackgroundColor = new(26, 26, 26, 255), + Size = new(80,1334), + Anchor = ObjectAnchor.Top | ObjectAnchor.Left | ObjectAnchor.Bottom, + }); + ser.Controls.Add(new Rectangle(Globals.LuskiTexture) + { + Size = new(80,80) + }); Controls.Add(channelpicker = new FlowLayout() { BackgroundColor = new(34,34,34,255), - Size = new(448, 1240), - Location = new(132, 0), + Size = new(448, 1232), + Location = new(80, 0), Anchor = ObjectAnchor.Top | ObjectAnchor.Left | ObjectAnchor.Bottom }); + channelpicker.Controls.Add(FriendManagerBtn = new RoundedButton() {Text = "Friends", Size = new(50, 80), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan}); + FriendManagerBtn.Clicked += FriendManagerBtnOnClicked; foreach (SocketGroupChannel ch in Globals.Luski.CurrentUser.Channels.Where(s => s is SocketGroupChannel).Cast()) { AddGroup(ch); @@ -90,7 +114,33 @@ public class MainScreen : Window { if (item.Channel is not null) AddFriend(item); } + Controls.Add(chat = new() {Location = new(528,0)}); + SocketTextChannel chan = Globals.Luski.GetChannel(Globals.Luski.CurrentUser.SelectedChannel).Result; + chat.UpdateTitle(chans.First(s => s.Channel.Id == chan.Id)); + IReadOnlyList messages = chan.GetMessages(200).Result; + foreach (SocketMessage message in messages.Reverse()) + { + chat.AddMessage(message); + } + Globals.Luski.UserStatusUpdate += LuskiOnUserStatusUpdate; DrawFrame(); return Task.CompletedTask; } + + private Task LuskiOnUserStatusUpdate(IUser before, IUser After) + { + if (before is not SocketRemoteUser Before || Before.FriendStatus != FriendStatus.Friends) return Task.CompletedTask; + Label stat = fr.Where(s => s.User.Id == before.Id).First()!.Status; + Invoke(new Action(() => + { + stat.Text = After.Status.ToString(); + })); + return Task.CompletedTask; + } + + private Task FriendManagerBtnOnClicked(IRenderObject arg) + { + //open the friend UI + return Task.CompletedTask; + } } \ No newline at end of file diff --git a/Luski/GUI/MainScreen/UI/Chat.cs b/Luski/GUI/MainScreen/UI/Chat.cs new file mode 100644 index 0000000..221ecc1 --- /dev/null +++ b/Luski/GUI/MainScreen/UI/Chat.cs @@ -0,0 +1,126 @@ +using GraphicsManager.Enums; +using GraphicsManager.Interfaces; +using GraphicsManager.Objects; +using Luski.GUI.MainScreen.Interfaces; +using Luski.net.Enums; +using Luski.net.JsonTypes; +using OpenTK.Graphics.ES20; +using OpenTK.Mathematics; +using OpenTK.Windowing.Common; +using OpenTK.Windowing.GraphicsLibraryFramework; + +namespace Luski.GUI.MainScreen.UI; + +public class Chat : UserControl +{ + private FlowLayout MessageFlow; + private UserControl titlecon, typecon; + private Label title, desc; + private Textbox tb; + private long id = -1; + public Chat() + { + Size = new(1520, 1334); + BackgroundColor = new(50, 50, 50, 255); + Anchor = ObjectAnchor.All; + Controls.Add(MessageFlow = new() + { + Size = new(1520, 1172), + Location = new(0, 80), + BackgroundColor = new(40,40,40,255), + Anchor = ObjectAnchor.All + }); + Controls.Add(titlecon = new UserControl(){Size = new(1520, 80), BackgroundColor = BackgroundColor}); + Controls.Add(typecon = new UserControl(){Location = new(0, 1252), Size = new(1520, 82), BackgroundColor = BackgroundColor}); + titlecon.Controls.Add(title = new Label(){Location = new(27, 40)}); + titlecon.Controls.Add(desc = new Label(){Color = new(161,161,161,255), Location = new(title.Location.X + title.Size.X + 5, title.Location.Y)}); + Globals.Luski.MessageReceived += LuskiOnMessageReceived; + typecon.Controls.Add(tb = new Textbox() + { + InsideColor = new(28, 28, 28, 255), + BorderColor = Color4.DarkCyan, + Location = new(15, 15), + Size = new(1490, 52) + }); + tb.KeyPress += TbOnKeyPress; + } + + private Task TbOnKeyPress(KeyboardKeyEventArgs arg) + { + if (arg.Key != Keys.Enter && arg.Key != Keys.KeyPadEnter) return Task.CompletedTask; + Thread t = new(() => Thr()); + t.Start(); + return Task.CompletedTask; + } + + private void Thr() + { + Globals.Luski.SendMessage(tb.Text, id); + tb.Text = string.Empty; + } + + private Task LuskiOnMessageReceived(SocketMessage arg) + { + if (id != arg.ChannelID) return Task.CompletedTask; + AddMessage(arg); + return Task.CompletedTask; + } + + public void Clear() + { + MessageFlow.Controls.Clear(); + lastm = null; + lastUser = null; + } + + public void UpdateTitle(IChannelPick channelPick) + { + //if (channelPick.Channel.Title is null) throw new Exception("You dont have a key for this channel"); + if (id == channelPick.Channel.Id) return; + id = channelPick.Channel.Id; + title.Text = channelPick.Channel.Title; + if (channelPick.Channel.Type == ChannelType.DM) + title.Text = (channelPick.Channel as SocketDMChannel)!.User.Username; + if (channelPick.Channel.Description is not null) + { + desc.Visible = true; + desc.Text = channelPick.Channel.Description; + desc.Location = new(title.Location.X + title.Size.X + 5, title.Location.Y); + } + else + { + desc.Visible = false; + } + } + + private SocketMessage? lastm = null; + private long? lastUser = null; + private ChatMessage? LastChatMessage = null; + + public void AddMessage(SocketMessage Message) + { + bool hasbeentenmin = false; + if (lastm is not null) + hasbeentenmin = + new DateTime(2022, 1, 1, 0, 0, 0, 0).AddMilliseconds(lastm.Id >> 22).ToLocalTime().AddMinutes(10) < + new DateTime(2022, 1, 1, 0, 0, 0, 0).AddMilliseconds(Message.Id >> 22).ToLocalTime(); + lastm = Message; + if (lastUser is null || lastUser != Message.AuthorID || hasbeentenmin) + { + if (Window is null || !Window.InvokeRequired) + MessageFlow.Controls.Add(LastChatMessage = new ChatMessage(Message)); + else + Window!.Invoke(new Action(() => { MessageFlow.Controls.Add(LastChatMessage = new ChatMessage(Message)); Window.DrawFrame(); })); + } + else + { + if (Window is null || !Window.InvokeRequired) + LastChatMessage!.AddMessage(Message); + else + Window!.Invoke(new Action(() => { LastChatMessage!.AddMessage(Message); Window!.DrawFrame(); })); + } + + lastUser = Message.AuthorID; + //Task.Delay(100); + } +} \ No newline at end of file diff --git a/Luski/GUI/MainScreen/UI/ChatMessage.cs b/Luski/GUI/MainScreen/UI/ChatMessage.cs index d760e89..1aa053e 100644 --- a/Luski/GUI/MainScreen/UI/ChatMessage.cs +++ b/Luski/GUI/MainScreen/UI/ChatMessage.cs @@ -11,25 +11,21 @@ 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 label1, label2; + private Label label1, label2, lastm; public ChatMessage(SocketMessage message) { + Size = new(1467, 74); + BackgroundColor = new(40, 40, 40, 255); Msg = message; IUser user = message.GetAuthor().Result; Anchor = ObjectAnchor.Left | ObjectAnchor.Right; Controls.Add(label1 = new Label() {Location = new(83, 9), Text = user.Username}); - Controls.Add(label2 = new Label() {Location = new(83, 40), Text = message.Context}); - if (Msg.Files != null && Msg.Files.Length > 0) - { - for (int i = 0; i < Msg.Files.Length; i++) - { - Controls.Add(new ContentEmbed(Msg.Files[i], Msg.ChannelID)); - } - } + DateTime time = new DateTime(2022, 1, 1, 0, 0, 0, 0).AddMilliseconds(Msg.Id >> 22).ToLocalTime(); string timestr; @@ -45,9 +41,33 @@ public class ChatMessage : UserControl { timestr = $"{time:M/dd/yyyy h:mm tt}"; } - Controls.Add(new Label() {Location = new(label1.Location.X + label1.Size.X + 4, 17), Text = timestr}); - Controls.Add(new Label() {Location = new(129, 17), Text = message.Context}); + Controls.Add(new Label() {Location = new(label1.Location.X + label1.Size.X + 4, 9), Text = timestr}); Controls.Add(new Rectangle(new Texture(user.GetAvatar().Result)) { Location = new(15, 3), Size = new(58, 58) }); + Controls.Add(label2 = new Label() {Location = new(83, 40), 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))) + }); + } + } + + Size = new(Size.X, Controls[Controls.Length - 1].Location.Y + Controls[Controls.Length - 1].Size.Y + padding + 10); } public void AddMessage(SocketMessage msg) @@ -64,11 +84,26 @@ public class ChatMessage : UserControl Controls.Add(newLabel); if (msg.Files != null && msg.Files.Length > 0) { - for (int i = 0; i < msg.Files.Length; i++) + int row = 1; + int filesonrow = 0; + for (int i = 0; i < Msg.Files.Length; i++) { - Controls.Add(new ContentEmbed(msg.Files[i], Msg.ChannelID)); + 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