diff --git a/Luski/Clesses/Settings.cs b/Luski/Clesses/Settings.cs new file mode 100644 index 0000000..f9fef7f --- /dev/null +++ b/Luski/Clesses/Settings.cs @@ -0,0 +1,30 @@ +using System.Text.Json.Serialization; + +namespace Luski.Clesses; + +public class Settings +{ + [JsonInclude] + [JsonPropertyName("scale")] + public double Scale { get; set; } = 1; + [JsonInclude] + [JsonPropertyName("perscrollpixels")] + public uint PerScrollPixels { get; set; } = 20; + [JsonInclude] + [JsonPropertyName("multithreadpercent")] + public uint MultiThreadPercent { get; set; } = 50; + [JsonInclude] + [JsonPropertyName("loadperchannel")] + public int LoadPerChannel { get; set; } = 50; +} + +[JsonSerializable(typeof(Settings))] +[JsonSourceGenerationOptions( + GenerationMode = JsonSourceGenerationMode.Default, + PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified, + WriteIndented = true, + DefaultIgnoreCondition = JsonIgnoreCondition.Never)] +internal partial class SettingsContext : JsonSerializerContext +{ + +} \ No newline at end of file diff --git a/Luski/Clesses/UpdaterSettings.cs b/Luski/Clesses/UpdaterSettings.cs new file mode 100644 index 0000000..5e3a68a --- /dev/null +++ b/Luski/Clesses/UpdaterSettings.cs @@ -0,0 +1,42 @@ +using System.Text.Json.Serialization; +using Luski.net.Enums; + +namespace Luski.Clesses; + +public class UpdaterSettings +{ + [JsonInclude] + [JsonPropertyName("self_contained")] + public bool SelfContained { get; set; } = false; + + [JsonInclude] + [JsonPropertyName("updater")] + public string? Updater { get; set; } = null; + + [JsonInclude] + [JsonPropertyName("branch")] + public Branch Branch { get; set; } = Branch.Beta; + + [JsonInclude] + [JsonPropertyName("platform")] + public string Platform { get; set; } = "linux-x64"; + + [JsonInclude] + [JsonPropertyName("auto_launch")] + public bool AutoLaunch { get; set; } = true; + + [JsonInclude] + [JsonPropertyName("update_check")] + public bool AutoUpdateCheck { get; set; } = true; +} + +[JsonSerializable(typeof(UpdaterSettings))] +[JsonSourceGenerationOptions( + GenerationMode = JsonSourceGenerationMode.Default, + PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified, + WriteIndented = true, + DefaultIgnoreCondition = JsonIgnoreCondition.Never)] +internal partial class UpdaterSettingsContext : JsonSerializerContext +{ + +} diff --git a/Luski/GUI/MainScreen.cs b/Luski/GUI/MainScreen.cs index 9df4b06..599ddee 100644 --- a/Luski/GUI/MainScreen.cs +++ b/Luski/GUI/MainScreen.cs @@ -1,3 +1,6 @@ +using System.Diagnostics; +using System.Reflection; +using GraphicsManager; using GraphicsManager.Enums; using GraphicsManager.Interfaces; using GraphicsManager.Objects; @@ -24,7 +27,8 @@ public class MainScreen : Window WindowBorder = WindowBorder.Fixed, APIVersion = new Version(3, 2), StartFocused = true, - Size = new OpenTK.Mathematics.Vector2i(481, 838), + Size = new Vector2i((int)(240.5 * Globals.Settings.Scale), (int)(419 * Globals.Settings.Scale)), + Icon = Globals.Icon }; private TabControl tc; @@ -36,13 +40,44 @@ public class MainScreen : Window public MainScreen() : base(Settings) { - Controls.Add(ca = new CreateAccount() {Visible = false}); + VSync = VSyncMode.On; + Globals.DefaultFont = + Font.MakeEmbeddedFont("Luski.Resources.Fonts.OpenSans-Regular.ttf", Assembly.GetExecutingAssembly()); + Globals.DefaultFont.PixelHeight = (uint)(12 * Globals.Settings.Scale); + //Font.MakeFontFromSystem((uint)(12 * Globals.Settings.Scale)); + Globals.LuskiTexture = TextureManager.AddTexture(Tools.GetResourceBytes(Assembly.GetExecutingAssembly(), + "Luski.Resources.Textures.Luski.png")); + + CenterWindow(0); + Controls.Add(ca = new CreateAccount()); + ca.Visible = false; ca.ChangeToApp += LoginOnChangeToApp; Controls.Add(login = new Login()); login.ChangeToApp += LoginOnChangeToApp; login.ChangeToCa += LoginOnChangeToCa; - Thread t = new(_ => Encryption.GenerateKeys()); + + Thread t = new(_ => + { + Encryption.GenerateKeys(); + + }); t.Start(); + WindowLoaded += OnWindowLoaded; + } + + private Task OnWindowLoaded(Window arg) + { + if (Globals.UpdaterSettings.AutoUpdateCheck && new HttpClient().GetAsync($"https://www.jacobtech.com/Updater/GetProgramVersion?directory=Luski&branch={Globals.UpdaterSettings.Branch}&selfcontained={Globals.UpdaterSettings.SelfContained.ToString().ToLower()}&platform={Globals.UpdaterSettings.Platform}").Result.Content.ReadAsStringAsync().Result != FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion) + { + var update = new UpdateWindow(); + var result = update.ShowDialogue(this); + if (result == UpdateWindow.DialogueResult.Yes) + { + Globals.Download = true; + Close(); + } + } + return Task.CompletedTask; } private Task LoginOnChangeToCa() @@ -93,29 +128,66 @@ public class MainScreen : Window } } - private Task ChannelOnClickCon(IChannelPick arg) + private CancellationTokenSource? channelCancellationToken = null; + private async Task ChannelOnClickCon(IChannelPick arg) { try { - if (!chat.Visible) - { - chat.Visible = true; - tc.Visible = false; - } - chat!.UpdateTitle(arg); - chat.Clear(); - IReadOnlyList messages = arg.Channel.GetMessages(200).Result; - foreach (SocketMessage message in messages.Reverse()) - { - chat.AddMessage(message); - } - DrawFrame(); + BlockDraw = true; + Thread t = new(a => cc(a)); + t.Start(arg); } catch (Exception e) { Console.WriteLine(e); } - return Task.CompletedTask; + } + + private void cc(object argg) + { + try + { + IChannelPick arg = (IChannelPick)argg; + Invoke(new Action(() => + { + chat!.UpdateTitle(arg); + })); + Console.WriteLine("Checking token"); + if (channelCancellationToken is not null) + { + Console.WriteLine("Cancling token"); + channelCancellationToken.Cancel(false); + } + channelCancellationToken = new CancellationTokenSource(); + Globals.Luski.ChangeChannel(arg.Channel.Id, channelCancellationToken.Token).Wait(); + Invoke(new Action(() => + { + chat!.Clear(); + })); + IReadOnlyList messages = arg.Channel.GetMessages(channelCancellationToken.Token, Globals.Settings.LoadPerChannel).Result; + + foreach (SocketMessage message in messages.Reverse()) + { + if (channelCancellationToken.Token.IsCancellationRequested) return; + Invoke(new Action(() => + { + chat!.AddMessage(message); + })); + } + if (channelCancellationToken.Token.IsCancellationRequested) return; + channelCancellationToken = null; + Invoke(new Action(() => + { + BlockDraw = false; + chat!.MessageFlow.ScrollToBottom(); + DrawFrame(); + })); + } + catch (Exception e) + { + if (e.Message.Contains("A task was canceled")) return; + Console.WriteLine(e); + } } private Task LoginOnChangeToApp() @@ -123,17 +195,30 @@ public class MainScreen : Window Controls.Clear(); BlockDraw = true; Title = "Luski"; - Size = new(2048, 1334); + // string Public, Private; + // using (RSACryptoServiceProvider cryptoServiceProvider = new RSACryptoServiceProvider(Encryption.NewKeySize)) + //{ + // Private = cryptoServiceProvider.ToXmlString(true); + // Public = cryptoServiceProvider.ToXmlString(false); + //} + // Luski.net.Encryption.File.Channels.AddKey(69, Private); + //Clip + // Console.WriteLine(Public); + Globals.Luski.SetMultiThreadPercent(Globals.Settings.MultiThreadPercent); + Size = new((int)(1024 * Globals.Settings.Scale), (int)(667 * Globals.Settings.Scale)); + DateTime start = DateTime.Now; + CenterWindow(0); + DateTime start1 = DateTime.Now; WindowBorder = WindowBorder.Resizable; BackgroundColor = new Color4(34, 34, 34, 255); - 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}); + Controls.Add(new Rectangle(TextureManager.AddTexture(Globals.Luski.CurrentUser.GetAvatar(CancellationToken.None).Result)) { Anchor = ObjectAnchor.Bottom | ObjectAnchor.Left, Size = new((int)(35 * Globals.Settings.Scale)), Location = new((int)(47 * Globals.Settings.Scale), (int)(624 * Globals.Settings.Scale))}); + Controls.Add(new Label(){ Font = Globals.DefaultFont, Anchor = ObjectAnchor.Bottom | ObjectAnchor.Left, Location = new((int)(86 * Globals.Settings.Scale), (int)(635.5 * Globals.Settings.Scale)), Text = Globals.Luski.CurrentUser.Username}); FlowLayout ser; - Controls.Add(chat = new() {Location = new(528,0)}); + Controls.Add(chat = new(this) {Location = new((int)(270 * Globals.Settings.Scale),0)}); Controls.Add(ser = new FlowLayout() { BackgroundColor = new(26, 26, 26, 255), - Size = new(80,1334), + Size = new((int)(40 * Globals.Settings.Scale),(int)(667 * Globals.Settings.Scale)), Anchor = ObjectAnchor.Top | ObjectAnchor.Left | ObjectAnchor.Bottom, }); @@ -143,9 +228,12 @@ public class MainScreen : Window Size = chat.Size, BackgroundColor = chat.BackgroundColor, Anchor = ObjectAnchor.All, - Visible = false + Visible = false, + TitleFont = Globals.DefaultFont, + Border = (int)( 10 * Globals.Settings.Scale), + TabSpace = (int)(5 * Globals.Settings.Scale), }); - tc.AddPage("Frineds", friends = new FlowLayout() + tc.AddPage("Friends", friends = new FlowLayout() { BackgroundColor = new(45,45,45,255) }); @@ -156,18 +244,19 @@ public class MainScreen : Window tc.AddPage("Add Friend", new AddFriendPage(this)); ser.Controls.Add(new Rectangle(Globals.LuskiTexture) { - Size = new(80,80), + Size = new((int)(40 * Globals.Settings.Scale)), }); Controls.Add(channelpicker = new FlowLayout() { BackgroundColor = new(34,34,34,255), - Size = new(448, 1232), - Location = new(80, 0), + Size = new((int)(230 * Globals.Settings.Scale), (int)(616 * Globals.Settings.Scale)), + Location = new((int)(40 * Globals.Settings.Scale), 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}); + channelpicker.Controls.Add(FriendManagerBtn = new RoundedButton() { Font = Globals.DefaultFont, Text = "Friends", Size = new((int)(40* Globals.Settings.Scale)), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan}); FriendManagerBtn.Clicked += FriendManagerBtnOnClicked; + Console.WriteLine("Templates loaded in " + (DateTime.Now - start).TotalSeconds + " seconds"); foreach (SocketGroupChannel ch in Globals.Luski.CurrentUser.Channels.Where(s => s is SocketGroupChannel).Cast()) { AddGroup(ch); @@ -176,28 +265,52 @@ public class MainScreen : Window { if (item.Channel is not null) AddFriend(item); } + Console.WriteLine("Channels done in " + (DateTime.Now - start).TotalSeconds + " seconds"); - SocketTextChannel chan = Globals.Luski.GetChannel(Globals.Luski.CurrentUser.SelectedChannel).Result; + SocketTextChannel chan = Globals.Luski.GetChannel(Globals.Luski.CurrentUser.SelectedChannel, CancellationToken.None).Result; chat.UpdateTitle(chans.First(s => s.Channel.Id == chan.Id)); - IReadOnlyList messages = chan.GetMessages(200).Result; - foreach (SocketMessage message in messages.Reverse()) + try { - chat.AddMessage(message); + IReadOnlyList messages = chan.GetMessages(CancellationToken.None, Globals.Settings.LoadPerChannel).Result; + Console.WriteLine("Messages done in " + (DateTime.Now - start).TotalSeconds + " seconds"); + foreach (SocketMessage message in messages.Reverse()) + { + chat.AddMessage(message); + } + chat.MessageFlow.ScrollToBottom(); } - Globals.Luski.OnError += LuskiOnOnError; - Globals.Luski.UserStatusUpdate += LuskiOnUserStatusUpdate; - Globals.Luski.ReceivedFriendRequest += LuskiOnReceivedFriendRequest; - Globals.Luski.FriendRequestResult += LuskiOnFriendRequestResult; + catch (Exception e) + { + Console.WriteLine(e); + ChannelOnClickCon(chans.Where(s => s.Channel.Id == 0).First()); + } + + + Console.WriteLine("Messages Fonts done in " + (DateTime.Now - start).TotalSeconds + " seconds"); foreach (SocketRemoteUser cufr in Globals.Luski.CurrentUser.FriendRequests) { AddFriendRequest(cufr); } - + Console.WriteLine("FR done in " + (DateTime.Now - start).TotalSeconds + " seconds"); BlockDraw = false; DrawFrame(); + Console.WriteLine("GUI done in " + (DateTime.Now - start1).TotalSeconds + " seconds"); + MainShow += OnMainShow; + MainShow.Invoke(); return Task.CompletedTask; } + private Task OnMainShow() + { + Globals.Luski.OnError += LuskiOnOnError; + Globals.Luski.UserStatusUpdate += LuskiOnUserStatusUpdate; + Globals.Luski.ReceivedFriendRequest += LuskiOnReceivedFriendRequest; + Globals.Luski.FriendRequestResult += LuskiOnFriendRequestResult; + return Task.CompletedTask; + } + + public event Func MainShow; + private Task LuskiOnOnError(Exception arg) { Console.WriteLine(arg); @@ -206,6 +319,7 @@ public class MainScreen : Window private Task LuskiOnFriendRequestResult(SocketRemoteUser arg1, bool arg2) { + Console.WriteLine("new result"); Invoke(new Action(() => { RemoveFriendRequest(arg1); @@ -225,7 +339,9 @@ public class MainScreen : Window private Task LuskiOnUserStatusUpdate(IUser before, IUser After) { - if (before is not SocketRemoteUser Before || Before.FriendStatus != FriendStatus.Friends) return Task.CompletedTask; + Console.WriteLine(before); + Console.WriteLine(After); + if (before is not SocketRemoteUser Before || Before.FriendStatus != FriendStatus.Friends || Before.Id == 0) return Task.CompletedTask; Label stat = fr.Where(s => s.User.Id == before.Id).First()!.Status; Invoke(new Action(() => { diff --git a/Luski/GUI/MainScreen/UI/AddFriendPage.cs b/Luski/GUI/MainScreen/UI/AddFriendPage.cs index 4faf17b..eae05af 100644 --- a/Luski/GUI/MainScreen/UI/AddFriendPage.cs +++ b/Luski/GUI/MainScreen/UI/AddFriendPage.cs @@ -15,9 +15,9 @@ public class AddFriendPage : FlowLayout public AddFriendPage(MainScreen Parent) { this.Screen = Parent; - Size = new(400, 96); + Size = new((int)(200 * Globals.Settings.Scale), (int)(48 * Globals.Settings.Scale)); BackgroundColor = new(45,45,45,255); - Controls.Add(Input = new Textbox() { Anchor = ObjectAnchor.Left | ObjectAnchor.Top | ObjectAnchor.Right, Location = new(15,15), Size = new(370,40), InsideColor = new(28,28,28,255), BorderColor = Color4.DarkCyan }); + Controls.Add(Input = new Textbox() { Anchor = ObjectAnchor.Left | ObjectAnchor.Top | ObjectAnchor.Right, Location = new((int)(7.5 * Globals.Settings.Scale)), Size = new((int)(185 * Globals.Settings.Scale),(int)(20 * Globals.Settings.Scale)), InsideColor = new(28,28,28,255), BorderColor = Color4.DarkCyan }); Input.KeyPress += InputOnKeyPress; } @@ -31,7 +31,7 @@ public class AddFriendPage : FlowLayout Input.BorderColor = Color4.Red; return Task.CompletedTask; } - SocketRemoteUser? result = Globals.Luski.SendFriendRequest(code).Result; + SocketRemoteUser? result = Globals.Luski.SendFriendRequest(code, CancellationToken.None).Result; if (result is null) Input.BorderColor = Color4.Red; else { diff --git a/Luski/GUI/MainScreen/UI/Chat.cs b/Luski/GUI/MainScreen/UI/Chat.cs index 9c44d6b..f97de7c 100644 --- a/Luski/GUI/MainScreen/UI/Chat.cs +++ b/Luski/GUI/MainScreen/UI/Chat.cs @@ -1,6 +1,8 @@ using GraphicsManager.Enums; +using GraphicsManager.Interfaces; using GraphicsManager.Objects; using Luski.GUI.MainScreen.Interfaces; +using Luski.net; using Luski.net.Enums; using Luski.net.JsonTypes; using OpenTK.Mathematics; @@ -11,39 +13,52 @@ namespace Luski.GUI.MainScreen.UI; public class Chat : UserControl { - private FlowLayout MessageFlow; + public FlowLayout MessageFlow; private UserControl titlecon, typecon; private Label title, desc; private Textbox tb; - private long id = -1; - public Chat() + private SocketTextChannel? Channel = null; + public Chat(MainScreen screen) { - Size = new(1520, 1334); + screen.MainShow += ScreenOnMainShow; + Size = new((int)(754 * Globals.Settings.Scale), (int)(667 * Globals.Settings.Scale)); BackgroundColor = new(50, 50, 50, 255); Anchor = ObjectAnchor.All; Controls.Add(MessageFlow = new() { - Size = new(1520, 1172), - Location = new(0, 80), + Size = new((int)(754 * Globals.Settings.Scale), (int)(586 * Globals.Settings.Scale)), + Location = new(0, (int)(40 * Globals.Settings.Scale)), BackgroundColor = new(40,40,40,255), - Anchor = ObjectAnchor.All + Anchor = ObjectAnchor.All, + HScrollPixels = Globals.Settings.PerScrollPixels }); - Controls.Add(titlecon = new UserControl(){Anchor = ObjectAnchor.Left | ObjectAnchor.Top | ObjectAnchor.Right, Size = new(1520, 80), BackgroundColor = BackgroundColor}); - Controls.Add(typecon = new UserControl(){Anchor = ObjectAnchor.Left | ObjectAnchor.Bottom | ObjectAnchor.Right, 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; + Controls.Add(titlecon = new UserControl(){Anchor = ObjectAnchor.Left | ObjectAnchor.Top | ObjectAnchor.Right, Size = new((int)(754 * Globals.Settings.Scale), (int)(40 * Globals.Settings.Scale)), BackgroundColor = BackgroundColor}); + Controls.Add(typecon = new UserControl(){Anchor = ObjectAnchor.Left | ObjectAnchor.Bottom | ObjectAnchor.Right, Location = new(0, (int)(626 * Globals.Settings.Scale)), Size = new((int)(754 * Globals.Settings.Scale), (int)(41 * Globals.Settings.Scale)), BackgroundColor = BackgroundColor}); + titlecon.Controls.Add(title = new Label() + { + Font = Globals.DefaultFont, Location = new( + (int)((20 - (Globals.DefaultFont.PixelHeight / 2)) * Globals.Settings.Scale), + (int)((20 * Globals.Settings.Scale) - (Globals.DefaultFont.PixelHeight / 2))) + }); + titlecon.Controls.Add(desc = new Label(){ Font = Globals.DefaultFont, Color = new(161,161,161,255), Location = new(title.Location.X + title.Size.X + 5, title.Location.Y)}); typecon.Controls.Add(tb = new Textbox() { + Font = Globals.DefaultFont, InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan, - Location = new(15, 15), - Size = new(1490, 52), + Location = new((int)(7.5 * Globals.Settings.Scale)), + Size = new((int)(739 * Globals.Settings.Scale), (int)(26 * Globals.Settings.Scale)), Anchor = ObjectAnchor.All }); tb.KeyPress += TbOnKeyPress; } + private Task ScreenOnMainShow() + { + Globals.Luski.MessageReceived += LuskiOnMessageReceived; + return Task.CompletedTask; + } + private Task TbOnKeyPress(KeyboardKeyEventArgs arg) { if (arg.Key != Keys.Enter && arg.Key != Keys.KeyPadEnter) return Task.CompletedTask; @@ -54,15 +69,18 @@ public class Chat : UserControl private void Thr() { - Globals.Luski.SendMessage(tb.Text, id); + Globals.Luski.SendMessage(tb.Text, Channel!.Id, CancellationToken.None); Window!.Invoke(new Action(() => { tb.Text = string.Empty; })); } private Task LuskiOnMessageReceived(SocketMessage arg) { - Console.WriteLine(arg); - if (id != arg.ChannelID) return Task.CompletedTask; + if (Channel!.Id != arg.ChannelID) return Task.CompletedTask; + IRenderObject? reff = null; + if (MessageFlow.Controls.Length > 0) reff = MessageFlow.Controls[MessageFlow.Controls.Length - 1]; AddMessage(arg); + if (reff is null || (reff.Location.Y + reff.Size.Y <= MessageFlow.Size.Y && reff.Location.X >= 0)) Window.Invoke(new Action(() => { MessageFlow.ScrollToBottom();})); + return Task.CompletedTask; } @@ -75,12 +93,13 @@ public class Chat : UserControl 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; + if (Channel is not null && Channel!.Id == channelPick.Channel.Id) return; + Channel = channelPick.Channel; title.Text = channelPick.Channel.Title; + tb.WatermarkFont = Globals.DefaultFont; if (channelPick.Channel.Type == ChannelType.DM) title.Text = (channelPick.Channel as SocketDMChannel)!.User.Username; + tb.WatermarkText = "Message " + title.Text; if (channelPick.Channel.Description is not null) { desc.Visible = true; @@ -121,6 +140,5 @@ public class Chat : UserControl } 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 1aa053e..09a732b 100644 --- a/Luski/GUI/MainScreen/UI/ChatMessage.cs +++ b/Luski/GUI/MainScreen/UI/ChatMessage.cs @@ -1,9 +1,12 @@ +using GraphicsManager; using GraphicsManager.Enums; using GraphicsManager.Interfaces; using GraphicsManager.Objects; using GraphicsManager.Objects.Core; +using Luski.net.Enums; using Luski.net.Interfaces; using Luski.net.JsonTypes; +using OpenTK.Mathematics; using File = Luski.net.JsonTypes.File; namespace Luski.GUI.MainScreen.UI; @@ -14,16 +17,19 @@ public class ChatMessage : UserControl private static Font TimeFont = Font.MakeFontFromSystem(13); private SocketMessage Msg { get; } private Label label1, label2, lastm; + private static Dictionary Menues = new(); + private static Dictionary> Messages = new(); public ChatMessage(SocketMessage message) { - Size = new(1467, 74); + 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().Result; + IUser user = message.GetAuthor(CancellationToken.None).Result; Anchor = ObjectAnchor.Left | ObjectAnchor.Right; - Controls.Add(label1 = new Label() {Location = new(83, 9), Text = user.Username}); + Controls.Add(label1 = new Label() { Font = Globals.DefaultFont, Location = new((int)(42 * Globals.Settings.Scale), (int)(4.5 * Globals.Settings.Scale)), Text = user.Username}); @@ -41,9 +47,9 @@ 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, 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}); + Controls.Add(new Label() { Font = Globals.DefaultFont, Location = new(label1.Location.X + label1.Size.X + 4, (int)(4.5 * Globals.Settings.Scale)), Text = timestr}); + Controls.Add(new Rectangle(Globals.ms.TextureManager.AddTexture(user.GetAvatar(CancellationToken.None).Result)) { Location = new((int)(7.5 * Globals.Settings.Scale), (int)(1.5 * Globals.Settings.Scale)), Size = new((int)(29 * Globals.Settings.Scale)) }); + Controls.Add(label2 = new Label() { Font = Globals.DefaultFont, Location = new((int)(41.5 * Globals.Settings.Scale), (int)(20 * Globals.Settings.Scale)), Text = message.Context}); lastm = label2; if (Msg.Files != null && Msg.Files.Length > 0) { @@ -67,13 +73,57 @@ public class ChatMessage : UserControl } } + 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) @@ -129,9 +179,9 @@ public class ChatMessage : UserControl 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(15, label.Location.Y - (int)TimeFont.PixelHeight + (int)label.Font.PixelHeight), - Font = TimeFont + Location = new((int)(7.5 * Globals.Settings.Scale), label.Location.Y - (int)TimeFont.PixelHeight + (int)label.Font.PixelHeight), }; Controls.Add(m); diff --git a/Luski/GUI/MainScreen/UI/ContentEmbed.cs b/Luski/GUI/MainScreen/UI/ContentEmbed.cs index 0e0341c..877462b 100644 --- a/Luski/GUI/MainScreen/UI/ContentEmbed.cs +++ b/Luski/GUI/MainScreen/UI/ContentEmbed.cs @@ -39,7 +39,7 @@ public class ContentEmbed : UserControl Controls.Add(fileNameLabel = new Label() { Color = new(102/(float)255,227/(float)255,170/(float)255, 1), Text = file.Name, Location = new(64, 6)}); fileNameLabel.Clicked += FileNameLabelOnClicked; byte[] tempp = Tools.GetResourceBytes(Assembly.GetExecutingAssembly(), "Luski.Resources.Textures.Download.png"); - Controls.Add(new Rectangle(new Texture(tempp)) { Location = new(8, 6), Size = new(50, 50)}); + Controls.Add(new Rectangle(Globals.ms.TextureManager.AddTexture(tempp)) { Location = new(8, 6), Size = new(50, 50)}); int temp = fileNameLabel.Size.X + fileNameLabel.Location.X; int temp2 = fileSizeLabel.Size.X + fileSizeLabel.Location.X; ; if (temp >= temp2) Size = new(temp + 4, Size.Y); @@ -50,7 +50,7 @@ public class ContentEmbed : UserControl { string dir = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Downloads", "LuskiDownloads"); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); - Thread t = new(() => file.DownloadBytes(Path.Join(dir, file.Name), channel)); + Thread t = new(() => file.DownloadBytes(Path.Join(dir, file.Name), channel, CancellationToken.None)); t.Start(); return Task.CompletedTask; } diff --git a/Luski/GUI/MainScreen/UI/Friend.cs b/Luski/GUI/MainScreen/UI/Friend.cs index b51181e..06bbdfb 100644 --- a/Luski/GUI/MainScreen/UI/Friend.cs +++ b/Luski/GUI/MainScreen/UI/Friend.cs @@ -3,6 +3,7 @@ using GraphicsManager.Objects; using GraphicsManager.Objects.Core; using Luski.GUI.MainScreen.Interfaces; using Luski.net.JsonTypes; +using OpenTK.Mathematics; namespace Luski.GUI.MainScreen.UI; @@ -22,17 +23,29 @@ public class Friend : UserControl, IChannelPick public Friend(SocketRemoteUser person) { User = person; - Size = new(370, 96); + Size = new((int)(185 * Globals.Settings.Scale), (int)(48* Globals.Settings.Scale)); BackgroundColor = new(34, 34, 34, 255); - Controls.Add( r = new Rectangle(new Texture(person.GetAvatar().Result)) { Location = new(15,17), Size = new(58,58)}); - Controls.Add(Username = new Label() { Text = person.Username, Location = new(77,20)}); - Controls.Add(Status = new Label() { Text = person.Status.ToString(), Location = new(77,48)}); - //r.Clicked += AllOnClicked; - //Username.Clicked += AllOnClicked; - //Status.Clicked += AllOnClicked; + Controls.Add( r = new Rectangle(Globals.ms.TextureManager.AddTexture(person.GetAvatar(CancellationToken.None).Result)) { Location = new((int)(7.5 * Globals.Settings.Scale),(int)(8.5 * Globals.Settings.Scale)), Size = new((int)(29* Globals.Settings.Scale))}); + Controls.Add(Username = new Label() { Font = Globals.DefaultFont, Text = person.Username, Location = new((int)(38.5 * Globals.Settings.Scale),(int)(10 * Globals.Settings.Scale))}); + Controls.Add(Status = new Label() { Font = Globals.DefaultFont, Text = person.Status.ToString(), Location = new((int)(38.5 * Globals.Settings.Scale),(int)(24 * Globals.Settings.Scale))}); this.Clicked += AllOnClicked; + ContextMenu = new((int)(150 * Globals.Settings.Scale)); + RoundedButton rr; + ContextMenu.Items.Add(rr=new() + { + InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan, + Size = new((int)(25 * Globals.Settings.Scale)), Font = Globals.DefaultFont, Text = "Export Keys" + }); + rr.Clicked += RrOnClicked; } - + + private Task RrOnClicked(IRenderObject arg) + { + _ = User.Channel!.SendKeysToUsers(CancellationToken.None); + ContextMenu!.HideContext(Window!); + return Task.CompletedTask; + } + private Task AllOnClicked(IRenderObject arg) { if (ClickCon is not null) _ = ClickCon.Invoke(this); diff --git a/Luski/GUI/MainScreen/UI/FriendRequest.cs b/Luski/GUI/MainScreen/UI/FriendRequest.cs index af91f73..91259d4 100644 --- a/Luski/GUI/MainScreen/UI/FriendRequest.cs +++ b/Luski/GUI/MainScreen/UI/FriendRequest.cs @@ -18,22 +18,22 @@ public class FriendRequest : UserControl { this.User = User; this.Screen = Parent; - Size = new(400, 96); + Size = new((int)(200 * Globals.Settings.Scale), (int)(48* Globals.Settings.Scale)); BackgroundColor = new(34, 34, 34, 255); - Controls.Add(new Rectangle(new Texture(User.GetAvatar().Result)) { Location = new(15,17), Size = new(58,58)}); - Controls.Add(new Label() { Text = User.Username, Location = new(77,20)}); - Controls.Add(new Label() { Text = User.FriendStatus.ToString(), Location = new(77,48)}); + Controls.Add(new Rectangle(Globals.ms.TextureManager.AddTexture(User.GetAvatar(CancellationToken.None).Result)) { Location = new((int)(7.5 * Globals.Settings.Scale),(int)(8.5 * Globals.Settings.Scale)), Size = new((int)(29 * Globals.Settings.Scale))}); + Controls.Add(new Label() { Font = Globals.DefaultFont, Text = User.Username, Location = new((int)(38.5 * Globals.Settings.Scale),(int)(10 * Globals.Settings.Scale))}); + Controls.Add(new Label() { Font = Globals.DefaultFont, Text = User.FriendStatus.ToString(), Location = new((int)(38.5 * Globals.Settings.Scale),(int)(24 * Globals.Settings.Scale))}); if (User.FriendStatus == FriendStatus.PendingIn) { Controls.Add(Accept = new Rectangle() { - Anchor = ObjectAnchor.Top | ObjectAnchor.Right, BackgroundColor = Color4.Green, Location = new(254, 17), - Size = new(58, 58) + Anchor = ObjectAnchor.Top | ObjectAnchor.Right, BackgroundColor = Color4.Green, Location = new((int)(127 * Globals.Settings.Scale), (int)(8.5 * Globals.Settings.Scale)), + Size = new((int)(29 * Globals.Settings.Scale)) }); Controls.Add(Reject = new Rectangle() { - Anchor = ObjectAnchor.Top | ObjectAnchor.Right, BackgroundColor = Color4.Red, Location = new(327, 17), - Size = new(58, 58) + Anchor = ObjectAnchor.Top | ObjectAnchor.Right, BackgroundColor = Color4.Red, Location = new((int)(163.5 * Globals.Settings.Scale), (int)(8.5 * Globals.Settings.Scale)), + Size = new((int)(29 * Globals.Settings.Scale)) }); Accept.Clicked += AcceptOnClicked; Reject.Clicked += RejectOnClicked; @@ -42,14 +42,14 @@ public class FriendRequest : UserControl private Task RejectOnClicked(IRenderObject arg) { - _ = Globals.Luski.SendFriendResult(User.Id, false).Result; + _ = Globals.Luski.SendFriendResult(User.Id, false, CancellationToken.None).Result; Screen.RemoveFriendRequest(User); return Task.CompletedTask; } private Task AcceptOnClicked(IRenderObject arg) { - Screen.AddFriend(Globals.Luski.SendFriendResult(User.Id, true).Result); + Screen.AddFriend(Globals.Luski.SendFriendResult(User.Id, true, CancellationToken.None).Result); Screen.RemoveFriendRequest(User); return Task.CompletedTask; } diff --git a/Luski/GUI/MainScreen/UI/Group.cs b/Luski/GUI/MainScreen/UI/Group.cs index 49bfc96..2bb840d 100644 --- a/Luski/GUI/MainScreen/UI/Group.cs +++ b/Luski/GUI/MainScreen/UI/Group.cs @@ -3,6 +3,7 @@ using GraphicsManager.Objects; using GraphicsManager.Objects.Core; using Luski.net.JsonTypes; using Luski.GUI.MainScreen.Interfaces; +using OpenTK.Mathematics; namespace Luski.GUI.MainScreen.UI; @@ -15,22 +16,35 @@ public class Group : UserControl, IChannelPick public Group(SocketGroupChannel chan) { Channel = chan; - Size = new(370, 96); + Size = new((int)(185 * Globals.Settings.Scale), (int)(48* Globals.Settings.Scale)); BackgroundColor = new(34, 34, 34, 255); - Controls.Add( r = new Rectangle(new Texture(chan.GetPicture().Result)) { Location = new(15,17), Size = new(58,58)}); - Controls.Add(Username = new Label() { Text = chan.Title, Location = new(77,20)}); + Controls.Add( r = new Rectangle(Globals.ms.TextureManager.AddTexture(chan.GetPicture(CancellationToken.None).Result)) { Location = new((int)(7.5 * Globals.Settings.Scale),(int)(8.5 * Globals.Settings.Scale)), Size = new((int)(29* Globals.Settings.Scale))}); + Controls.Add(Username = new Label() { Font = Globals.DefaultFont, Text = chan.Title, Location = new((int)(38.5 * Globals.Settings.Scale),(int)(10 * Globals.Settings.Scale))}); string sl = "Online"; if (chan.Id != 0) { - sl = chan.Members.Count + " Memmbers"; + sl = chan.Members.Count + " Members"; } - Controls.Add(Status = new Label() { Text = sl, Location = new(77,48)}); - //r.Clicked += AllOnClicked; - //Username.Clicked += AllOnClicked; - //Status.Clicked += AllOnClicked; + Controls.Add(Status = new Label() { Font = Globals.DefaultFont, Text = sl, Location = new((int)(38.5 * Globals.Settings.Scale),(int)(24 * Globals.Settings.Scale))}); this.Clicked += AllOnClicked; + if (chan.Id == 0) return; + ContextMenu = new((int)(150 * Globals.Settings.Scale)); + RoundedButton rr; + ContextMenu.Items.Add(rr=new() + { + InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan, + Size = new((int)(25 * Globals.Settings.Scale)), Font = Globals.DefaultFont, Text = "Export Keys" + }); + rr.Clicked += RrOnClicked; } + private Task RrOnClicked(IRenderObject arg) + { + _ = Channel.SendKeysToUsers(CancellationToken.None); + ContextMenu!.HideContext(Window!); + return Task.CompletedTask; + } + private Task AllOnClicked(IRenderObject arg) { if (ClickCon is not null) _ = ClickCon.Invoke(this); diff --git a/Luski/GUI/StartPage/UI/CreateAccount.cs b/Luski/GUI/StartPage/UI/CreateAccount.cs index 97dde3a..7787b56 100644 --- a/Luski/GUI/StartPage/UI/CreateAccount.cs +++ b/Luski/GUI/StartPage/UI/CreateAccount.cs @@ -1,7 +1,6 @@ using GraphicsManager.Interfaces; using GraphicsManager.Objects; using Luski.net; -using Luski.net.Enums; using OpenTK.Mathematics; using OpenTK.Windowing.Common; using OpenTK.Windowing.GraphicsLibraryFramework; @@ -19,17 +18,16 @@ public class CreateAccount : UserControl public CreateAccount() { - Size = new(481, 838); - Controls.Add(new Rectangle(Globals.LuskiTexture) { Location = new(103,8), Size = new(276, 289)}); - Controls.Add(new Label() { Scale = 1.4f, Location = new(173,305), Text = "Luski", Color = new(243, 119, 53, 255) }); - Controls.Add(new Label() { Location = new(41,395), Text = "Email"}); - Controls.Add(Email = new Textbox() { Location = new(41,431), Size = new(401,41), InsideColor = new(28,28,28,255), BorderColor = Color4.DarkCyan }); - Controls.Add(new Label() { Location = new(41,490), Text = "Password" }); - Controls.Add(Password = new Textbox() { PasswordChar = '●', Location = new(41,531), Size = new(401, 41), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); - Controls.Add(new Label() { Location = new(41,580), Text = "Display Name" }); - Controls.Add(Username = new Textbox() { Location = new(41,616), Size = new(300, 41), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); - Controls.Add(button = new() { Text = "Create Account", Location = new(41, 700), Size = new(401, 71), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); - Controls.Add(rec = new Rectangle(){ Location = new(350, 585), Size = new(100), BackgroundColor = Color4.Red}); + Size = new((int)(240.5*Globals.Settings.Scale), (int)(419*Globals.Settings.Scale)); + Controls.Add(new Rectangle(Globals.LuskiTexture) { Location = new((int)(51.5 * Globals.Settings.Scale), (int)(4 * Globals.Settings.Scale)), Size = new((int)(138*Globals.Settings.Scale), (int)(144.5*Globals.Settings.Scale))}); + Label t; + Controls.Add(t=new Label() { Scale = 1.6f, Font = Globals.DefaultFont, Location = new((int)(85*Globals.Settings.Scale),(int)(153*Globals.Settings.Scale)), Text = "Luski", Color = new(243, 119, 53, 255) }); + t.Location = new((Size.X / 2) - (t.Size.X / 2), t.Location.Y); + Controls.Add(Email = new Textbox() { WatermarkFont = Globals.DefaultFont, WatermarkText = "Email", Font = Globals.DefaultFont, Location = new((int)(20.5 * Globals.Settings.Scale),(int)(215.5 * Globals.Settings.Scale)), Size = new((int)(200.5 * Globals.Settings.Scale),(int)(20.5 * Globals.Settings.Scale)), InsideColor = new(28,28,28,255), BorderColor = Color4.DarkCyan }); + Controls.Add(Password = new Textbox() { WatermarkFont = Globals.DefaultFont, WatermarkText = "Password", Font = Globals.DefaultFont, PasswordChar = '●', Location = new(Email.Location.X,(int)(265.5 * Globals.Settings.Scale)), Size = new(Email.Size.X, Email.Location.X), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); + Controls.Add(Username = new Textbox() { WatermarkFont = Globals.DefaultFont, WatermarkText = "Username", Font = Globals.DefaultFont, Location = new(Email.Location.X,(int)(308 * Globals.Settings.Scale)), Size = new((int)(150 * Globals.Settings.Scale), Email.Location.X), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); + Controls.Add(button = new() { Font = Globals.DefaultFont, Text = "Create Account", Location = new(Email.Location.X, (int)(350 * Globals.Settings.Scale)), Size = new((int)(200.5 * Globals.Settings.Scale), (int)(35.5 * Globals.Settings.Scale)), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); + Controls.Add(rec = new Rectangle(){ Location = new((int)(175 * Globals.Settings.Scale), (int)(292.5 * Globals.Settings.Scale)), Size = new((int)(50 * Globals.Settings.Scale)), BackgroundColor = Color4.Red}); Password.KeyPress += PasswordOnKeyPress; Email.KeyPress += EmailOnKeyPress; button.Clicked += ButtonOnClicked; @@ -50,7 +48,7 @@ public class CreateAccount : UserControl if (!arg[0].ToLower().EndsWith("png")) return Task.CompletedTask; Controls.Remove(rec); pfp = arg[0]; - rec = new(new(File.ReadAllBytes(arg[0]))){ Location = new(350, 585), Size = new(100) }; + rec = new(Globals.ms.TextureManager.AddTexture(File.ReadAllBytes(arg[0]))){ Location = new(350, 585), Size = new(100) }; Controls.Add(rec); Window!.DrawFrame(); return Task.CompletedTask; @@ -89,7 +87,7 @@ public class CreateAccount : UserControl pfp }; if (arr.Any(s => string.IsNullOrEmpty(s))) return Task.CompletedTask; - Globals.Luski = Server.CreateAccount(Email.Text, Password.Text, Username.Text, pfp, Globals.Branch); + Globals.Luski = Server.CreateAccount(Email.Text, Password.Text, Username.Text, pfp, CancellationToken.None, Globals.UpdaterSettings.Branch); ChangeToApp.Invoke(); } catch (Exception e) diff --git a/Luski/GUI/StartPage/UI/Login.cs b/Luski/GUI/StartPage/UI/Login.cs index 9593b29..56733f8 100644 --- a/Luski/GUI/StartPage/UI/Login.cs +++ b/Luski/GUI/StartPage/UI/Login.cs @@ -3,6 +3,7 @@ using GraphicsManager.Objects; using Luski.net; using OpenTK.Mathematics; using OpenTK.Windowing.Common; +using OpenTK.Windowing.Desktop; using OpenTK.Windowing.GraphicsLibraryFramework; namespace Luski.GUI.StartPage.UI; @@ -12,19 +13,19 @@ public class Login : UserControl private RoundedButton button; private Textbox Password, Email; private Label ca; - public event Func ChangeToApp; - public event Func ChangeToCa; + public event Func? ChangeToApp; + public event Func? ChangeToCa; public Login() { - Size = new(481, 838); - Controls.Add(new Rectangle(Globals.LuskiTexture) { Location = new(103,8), Size = new(276, 289)}); - Controls.Add(new Label() { Scale = 1.4f, Location = new(173,305), Text = "Luski", Color = new(243, 119, 53, 255) }); - Controls.Add(new Label() { Location = new(41,395), Text = "Email"}); - Controls.Add(Email = new Textbox() { Location = new(41,431), Size = new(401,41), InsideColor = new(28,28,28,255), BorderColor = Color4.DarkCyan }); - Controls.Add(new Label() { Location = new(41,521), Text = "Password" }); - Controls.Add(Password = new Textbox() { PasswordChar = '●', Location = new(41,562), Size = new(401, 41), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); - Controls.Add(ca = new Label() { Location = new(41,664), Text = "Create Account" }); - Controls.Add(button = new() { Text = "Login", Location = new(41, 700), Size = new(401, 71), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); + Size = new((int)(240.5*Globals.Settings.Scale), (int)(419*Globals.Settings.Scale)); + Controls.Add(new Rectangle(Globals.LuskiTexture) { Location = new((int)(51.5 * Globals.Settings.Scale), (int)(4 * Globals.Settings.Scale)), Size = new((int)(138*Globals.Settings.Scale), (int)(144.5*Globals.Settings.Scale))}); + Label t; + Controls.Add(t=new Label() { Scale = 1.6f, Font = Globals.DefaultFont, Location = new((int)(85*Globals.Settings.Scale),(int)(153*Globals.Settings.Scale)), Text = "Luski", Color = new(243, 119, 53, 255) }); + t.Location = new((Size.X / 2) - (t.Size.X / 2), t.Location.Y); + Controls.Add(Email = new Textbox() { WatermarkFont = Globals.DefaultFont, WatermarkText = "Email", Font = Globals.DefaultFont, Location = new((int)(20.5*Globals.Settings.Scale),(int)(215.5 * Globals.Settings.Scale)), Size = new((int)(200.5 * Globals.Settings.Scale),(int)(20.5 * Globals.Settings.Scale)), InsideColor = new(28,28,28,255), BorderColor = Color4.DarkCyan }); + Controls.Add(Password = new Textbox() { WatermarkFont = Globals.DefaultFont, WatermarkText = "Password", Font = Globals.DefaultFont, PasswordChar = '●', Location = new((int)(20.5*Globals.Settings.Scale),(int)(281 * Globals.Settings.Scale)), Size = new((int)(200.5 * Globals.Settings.Scale), (int)(20.5 * Globals.Settings.Scale)), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); + Controls.Add(ca = new Label() { Font = Globals.DefaultFont, Location = new((int)(20.5*Globals.Settings.Scale),(int)(332 * Globals.Settings.Scale)), Text = "Create Account" }); + Controls.Add(button = new() { Font = Globals.DefaultFont, Text = "Login", Location = new((int)(20.5*Globals.Settings.Scale), (int)(350 * Globals.Settings.Scale)), Size = new((int)(200.5 * Globals.Settings.Scale), (int)(35.5 * Globals.Settings.Scale)), InsideColor = new(28, 28, 28, 255), BorderColor = Color4.DarkCyan }); Password.KeyPress += PasswordOnKeyPress; Email.KeyPress += EmailOnKeyPress; button.Clicked += ButtonOnClicked; @@ -40,7 +41,7 @@ public class Login : UserControl private Task CaOnClicked(IRenderObject arg) { - ChangeToCa.Invoke(); + ChangeToCa!.Invoke(); return Task.CompletedTask; } @@ -63,8 +64,8 @@ public class Login : UserControl { try { - Globals.Luski = Server.Login(Email.Text, Password.Text, Globals.Branch).Result; - ChangeToApp.Invoke(); + Globals.Luski = Server.Login(Email.Text, Password.Text, CancellationToken.None, Globals.UpdaterSettings.Branch).Result; + ChangeToApp!.Invoke(); } catch (Exception e) { diff --git a/Luski/GUI/UpdateWindow.cs b/Luski/GUI/UpdateWindow.cs new file mode 100644 index 0000000..cdfaad9 --- /dev/null +++ b/Luski/GUI/UpdateWindow.cs @@ -0,0 +1,100 @@ +using GraphicsManager; +using GraphicsManager.Interfaces; +using GraphicsManager.Objects; +using OpenTK.Mathematics; +using OpenTK.Windowing.Desktop; +using OpenTK.Windowing.Common; + +namespace Luski.GUI; + +public class UpdateWindow : Window +{ + private RoundedButton yes, no; + private static readonly NativeWindowSettings Settings = new() + { + Title = "Update Available", + WindowBorder = WindowBorder.Fixed, + APIVersion = new Version(3, 2), + StartFocused = true, + Size = new OpenTK.Mathematics.Vector2i(481, 838), + Icon = Globals.Icon + }; + + public enum DialogueResult + { + Yes, + No, + Closed + } + + private DialogueResult Result = DialogueResult.Closed; + + public UpdateWindow() : base(Settings) + { + Label t; + Controls.Add(t = new Label() { Font = Globals.DefaultFont, Scale = 1.2f, Location = new((int)(17.5*Globals.Settings.Scale)), Text = "Luski has detected that your\nclient is on an older version\nfor your branch."}); + if (!Globals.Empty(Globals.UpdaterSettings.Updater)) + { + t.Text += "\n\nWould you like to update?"; + Controls.Add(yes = new() + { + Font = Globals.DefaultFont, Text = "Yes", + Location = new(t.Location.X, t.Location.Y + t.Size.Y + (int)(t.Scale * t.Font.PixelHeight)), + Size = new(t.Size.X, (int)(35.5 * Globals.Settings.Scale)), InsideColor = new(28, 28, 28, 255), + BorderColor = Color4.DarkCyan + }); + Controls.Add(no = new() + { + Font = Globals.DefaultFont, Text = "No", Location = new(t.Location.X, yes.Location.Y + yes.Size.Y + 20), + Size = new(yes.Size.X, (int)(35.5 * Globals.Settings.Scale)), InsideColor = new(28, 28, 28, 255), + BorderColor = Color4.DarkCyan + }); + Size = new(t.Location.X + t.Location.X + t.Size.X, no.Location.Y + no.Size.Y + t.Location.X); + yes.Clicked += YesOnClicked; + no.Clicked += NoOnClicked; + } + else + { + t.Text += "\n\nNo updater path was set\nSet a path for auto updates"; + Controls.Add(no = new() + { + Font = Globals.DefaultFont, Text = "Ok", + Location = new(t.Location.X, t.Location.Y + t.Size.Y + (int)(t.Scale * t.Font.PixelHeight)), + Size = new(t.Size.X, (int)(35.5 * Globals.Settings.Scale)), InsideColor = new(28, 28, 28, 255), + BorderColor = Color4.DarkCyan + }); + Size = new(t.Location.X + t.Location.X + t.Size.X, no.Location.Y + no.Size.Y + t.Location.X); + no.Clicked += NoOnClicked; + } + CenterWindow(); + } + + private Task NoOnClicked(IRenderObject arg) + { + Result = DialogueResult.No; + base.Close(); + return Task.CompletedTask; + } + + private Task YesOnClicked(IRenderObject arg) + { + Result = DialogueResult.Yes; + base.Close(); + return Task.CompletedTask; + } + + public DialogueResult ShowDialogue(Window? Parent = null) + { + try + { + if (Parent is not null) Parent.DrawFrame(); + StartRender(); + return Result; + } + finally + { + IsVisible = false; + //Dispose(); + } + } +} \ No newline at end of file diff --git a/Luski/Globals.cs b/Luski/Globals.cs index 18c4dcc..16d0701 100644 --- a/Luski/Globals.cs +++ b/Luski/Globals.cs @@ -1,16 +1,56 @@ using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; using GraphicsManager; using GraphicsManager.Objects.Core; +using Luski.Clesses; +using Luski.GUI.MainScreen; using Luski.net; using Luski.net.Enums; +using OpenTK.Windowing.Common.Input; namespace Luski; public class Globals { - public static Server Luski = null!; + public static bool Download { get; set; } = false; + public static Server Luski { get; set; } = null!; + public static MainScreen ms; + public static Settings Settings { get; set; } - public static Texture LuskiTexture = new(Tools.GetResourceBytes(Assembly.GetExecutingAssembly(), "Luski.Resources.Textures.Luski.png")); + public static Font DefaultFont { get; set; } + public static UpdaterSettings UpdaterSettings { get; set; } + + public static Texture LuskiTexture; + + public static TResult GetSettings(string path, JsonTypeInfo TypeInfo) where TResult : new() + { + TResult? @out; + if (!File.Exists(path)) + { + @out = new(); + Console.WriteLine("Overiding 1"); + File.WriteAllText(path, JsonSerializer.Serialize(@out, TypeInfo)); + } + + try + { + @out = JsonSerializer.Deserialize(File.ReadAllText(path), TypeInfo); + Console.WriteLine("Found"); + if (@out is null) + { + Console.WriteLine("Overiding 2"); + @out = new(); + } + } + catch + { + Console.WriteLine("Overiding 3"); + @out = new(); + } + File.WriteAllText(path, JsonSerializer.Serialize(@out, TypeInfo)); + return @out; + } public static string JT { @@ -22,22 +62,24 @@ public class Globals tmp = Path.Combine(Environment.GetEnvironmentVariable("HOME")!, ".config/"); tmp += "JacobTech"; } + + if (!Directory.Exists(tmp)) Directory.CreateDirectory(tmp); + if (!Directory.Exists(Path.Combine(tmp, "Luski"))) Directory.CreateDirectory(Path.Combine(tmp, "Luski")); return tmp; } } - - public static Branch Branch + public static WindowIcon Icon { get; set; } + + public static string LuskiPath { get { - if (!File.Exists(Path.Combine(Environment.CurrentDirectory, "branch.txt"))) File.WriteAllText(Path.Combine(Environment.CurrentDirectory, "branch.txt"), ((int)Branch.Beta).ToString()); - return File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "branch.txt")) switch - { - "0" => Branch.Dev, - "1" => Branch.Beta, - "2" => Branch.Master, - _ => Branch.Beta - }; + return Path.Combine(JT, "Luski"); } } + + public static bool Empty(string? str) + { + return (string.IsNullOrEmpty(str) || string.IsNullOrWhiteSpace(str)); + } } \ No newline at end of file diff --git a/Luski/Luski.csproj b/Luski/Luski.csproj index 02ca044..2993119 100644 --- a/Luski/Luski.csproj +++ b/Luski/Luski.csproj @@ -5,15 +5,26 @@ net6.0 enable enable + 1.0.1.2 + JacobTech, LLC + + + + + none - - + + + + Luski.ico + + diff --git a/Luski/Luski.ico b/Luski/Luski.ico new file mode 100755 index 0000000..413cb3b Binary files /dev/null and b/Luski/Luski.ico differ diff --git a/Luski/Program.cs b/Luski/Program.cs index adc49ce..65ba94b 100644 --- a/Luski/Program.cs +++ b/Luski/Program.cs @@ -1,12 +1,78 @@ -using Luski.GUI.MainScreen; +using System.Diagnostics; +using System.Reflection; +using System.Security.Cryptography; +using Luski; +using Luski.Clesses; +using Luski.GUI.MainScreen; +using Luski.net; +using OpenTK.Windowing.Common.Input; +using SixLabors.ImageSharp.PixelFormats; try { - MainScreen t = new MainScreen(); - t.StartRender(); - t.Dispose(); + + Globals.Settings = Globals.GetSettings(Path.Combine(Globals.LuskiPath, "Settings.json"), SettingsContext.Default.Settings); + Globals.UpdaterSettings = Globals.GetSettings(Path.Combine(Globals.LuskiPath, "UpdaterSettings.json"), UpdaterSettingsContext.Default.UpdaterSettings); + + Assembly assembly = Assembly.GetExecutingAssembly(); + Stream? resource_stream = assembly.GetManifestResourceStream($"Luski.Resources.Textures.Luski.png"); + MemoryStream ms = new(); + resource_stream?.CopyTo(ms); + var Logo = SixLabors.ImageSharp.Image.Load(ms.ToArray()); + + var pixels = new List(4 * Logo.Width * Logo.Height); + + for (int y = 0; y < Logo.Height; y++) + { + var row = Logo.GetPixelRowSpan(y); + + for (int x = 0; x < Logo.Width; x++) + { + pixels.Add(row[x].R); + pixels.Add(row[x].G); + pixels.Add(row[x].B); + pixels.Add(row[x].A); + } + } + Globals.Icon = new WindowIcon(new Image(Logo.Width, Logo.Height, pixels.ToArray())); + Globals.ms = new MainScreen(); + Globals.ms.StartRender(); + Globals.ms.Dispose(); } catch (Exception ex) { Console.WriteLine(ex); +} + +if (Globals.Download) +{ + Console.WriteLine("Auto Update Starting"); + List arguments = new List + { + "--process", + Process.GetCurrentProcess().ProcessName, + "--remotedirectory", + "Luski", + "--localdirectory", + AppDomain.CurrentDomain.BaseDirectory, + "--branch", + Globals.UpdaterSettings.Branch.ToString(), + "--selfcontained", + Globals.UpdaterSettings.SelfContained.ToString().ToLower(), + "--platform", + Globals.UpdaterSettings.Platform, + "--setconfig", + Path.Combine(Globals.LuskiPath, "UpdaterSettings.json") + }; + if (Globals.UpdaterSettings.AutoLaunch) + { + arguments.Add("--dll"); + arguments.Add(AppDomain.CurrentDomain.FriendlyName); + } + Process p = new(); + p.StartInfo.FileName = Globals.UpdaterSettings.Updater; + p.StartInfo.WorkingDirectory = new FileInfo(Globals.UpdaterSettings.Updater!).Directory!.FullName; + p.StartInfo.Arguments = $"\"{string.Join("\" \"", arguments)}\""; + p.Start(); + Environment.Exit(0); } \ No newline at end of file diff --git a/Luski/Resources/Fonts/OpenSans-Regular.ttf b/Luski/Resources/Fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000..1dc226d Binary files /dev/null and b/Luski/Resources/Fonts/OpenSans-Regular.ttf differ