diff --git a/] b/] deleted file mode 100644 index 6b5149a..0000000 --- a/] +++ /dev/null @@ -1,482 +0,0 @@ -using System.Diagnostics; -using System.Text; -using System.Text.RegularExpressions; -using Discord; -using Discord.WebSocket; -using DiscordRPC; -using Microsoft.Extensions.Configuration; -using RestSharp; -using Terminal.Gui; -using Terminal.Gui.Trees; -using Attribute = Terminal.Gui.Attribute; -using Button = Terminal.Gui.Button; -using Color = Terminal.Gui.Color; - -namespace chord -{ - public class Program - { - private ListView chatBoxList; - private List currentChannelMessages; - private ulong currentSelectedChannel; - private ulong currentSelectedGuild; - private SortedDictionary> guilds; - private DiscordRpcClient rpcClient; - private Settings settings; - private Window window; - - public static void Main() - { - new Program().Start(); - } - - private async void Start() - { - try { -#if DEBUG - var config = new ConfigurationBuilder() - .AddJsonFile("config.json") - .Build(); -#else - var config = new ConfigurationBuilder() - .AddJsonFile($"{Environment.GetEnvironmentVariable("HOME")}/.config/chord/config.json") - .Build(); -#endif - - settings = config.Get(); - - var client = new DiscordSocketClient(new DiscordSocketConfig - { AlwaysDownloadUsers = true, GatewayIntents = GatewayIntents.All }); - - await client.LoginAsync(TokenType.Bot, settings.Token); - await client.StartAsync(); - - if (settings.EnableRichPresence) { - rpcClient = new DiscordRpcClient("923436807297859625"); - rpcClient.Initialize(); - rpcClient.SetPresence(new RichPresence()); - } - - Application.Init(); - - window = new Window("chord") - { - X = 0, - Y = 1, - Width = Dim.Fill(), - Height = Dim.Fill(), - ColorScheme = - { - Normal = new Attribute(Color.White, Color.Black) - } - }; - - var menuBar = buildMenu(); - - var loadingLabel = new Label("Loading...") - { - X = 0, - Y = 0, - Width = Dim.Percent(50), - Height = Dim.Height(50), - }; - - client.Ready += () => - { - guilds = new SortedDictionary>(); - - foreach (var guild in client.Guilds) - { - guilds.Add(guild.Id, new List()); - - foreach (var channel in guild.TextChannels) - { - var findGuild = guilds.GetValueOrDefault(guild.Id); - - if (channel.Users.ToList().Find(user => user.Id == client.CurrentUser.Id) == null) continue; - if (findGuild == null) continue; - findGuild.Add(channel.Id); - - findGuild.Sort(); - } - } - - var serverList = buildServerList(); - var channelList = buildChannelList(serverList); - var chatBox = buildChatBox(serverList); - var messageBox = buildMessageBox(serverList, chatBox); - var userList = buildUserList(chatBox); - - var serverListList = new ListView - { - X = 0, - Y = 0, - Width = Dim.Fill(), - Height = Dim.Fill() - }; - - var guildNames = guilds.Select(guild => client.GetGuild(guild.Key).Name).ToList(); - - serverListList.SetSource(guildNames); - - var channelListTree = new TreeView - { - X = 0, - Y = 0, - Width = Dim.Fill(), - Height = Dim.Fill() - }; - - chatBoxList = new ListView - { - X = 0, - Y = 0, - Width = Dim.Fill(), - Height = Dim.Fill() - }; - - var messageBoxText = new TextView - { - X = 0, - Y = 0, - Width = Dim.Percent(95), - Height = Dim.Fill() - }; - - var messageBoxSend = new Button("Send", true) - { - X = Pos.Right(messageBoxText) - 2, - Y = 0 - }; - - var userListTree = new TreeView - { - X = 0, - Y = 0, - Width = Dim.Fill(), - Height = Dim.Fill() - }; - - serverListList.OpenSelectedItem += args => - { - channelListTree.ClearObjects(); - - currentSelectedGuild = guilds.Keys.ToList()[args.Item]; - - var channelNames = guilds.GetValueOrDefault(currentSelectedGuild)! - .Select(channel => client.GetGuild(currentSelectedGuild).GetTextChannel(channel).Name).ToList(); - - var categoryDict = new SortedDictionary(); - - foreach (var categories in client.GetGuild(currentSelectedGuild).CategoryChannels) - { - var categoryName = Regex.Replace(categories.Name, @"[^\u0000-\u007F]+", string.Empty); - var node = new TreeNode(categoryName); - - foreach(var channel in categories.Channels) - { - if (channel.GetType().Name == "SocketTextChannel") - { - var channelName = Regex.Replace(channel.Name, @"[^\u0000-\u007F]+", string.Empty); - var channelNode = new TreeNode(channelName); - channelNode.Tag = new { Id = channel.Id }; - - node.Children.Add(channelNode); - } - } - - categoryDict.Add(categories.Id, node); - } - - foreach (var category in categoryDict) - { - channelListTree.AddObject(category.Value); - } - - if (settings.EnableRichPresence) { - rpcClient.UpdateDetails($"Chatting in {client.GetGuild(currentSelectedGuild).Name}"); - } - }; - - channelListTree.SelectionChanged += async (arg1, arg2) => - { - userListTree.ClearObjects(); - - try { - currentSelectedChannel = (ulong)arg2.NewValue.Tag.GetType().GetProperty("Id").GetValue(arg2.NewValue.Tag); - } catch { - return; - } - - try { - var restSharpClient = new RestClient("https://discord.com/api/v9"); - var restSharpReq = new RestRequest($"channels/{currentSelectedChannel}/messages"); - restSharpClient.AddDefaultHeader("Authorization", settings.Token); - - var response = await restSharpClient.GetAsync>(restSharpReq); - - var messages = new List(); - - foreach (var msg in response) - { - var msgNewLines = msg.content.Split("\n").ToList(); - - var firstMsg = msgNewLines[0]; - - msgNewLines.RemoveAt(0); - msgNewLines.Reverse(); - - messages.AddRange(msgNewLines.Select(message => $"{message}")); - - messages.Add($"{msg.author.username}#{msg.author.discriminator} | {firstMsg}"); - - if (msg.embeds.Count != 0) - messages.Add($"{msg.author.username}#{msg.author.discriminator} | [Unable to display embed]"); - - if (msg.attachments.Count == 0) continue; - messages.AddRange(msg.attachments - .Select(attachment => $"{msg.author.username}#{msg.author.discriminator} | {attachment.url}") - .Select(dummy => dummy)); - } - - messages.Reverse(); - - await chatBoxList.SetSourceAsync(messages); - currentChannelMessages = messages; - - chatBoxList.ScrollDown(currentChannelMessages.Count - chatBoxList.Bounds.Height); - chatBoxList.SelectedItem = currentChannelMessages.Count - 1; - - var rolesDict = new SortedDictionary(); - - foreach (var roles in client.GetGuild(currentSelectedGuild).Roles) - { - var roleName = Regex.Replace(roles.Name, @"[^\u0000-\u007F]+", string.Empty); - var node = new TreeNode(roleName); - - foreach (var users in roles.Members) - { - node.Children.Add(new TreeNode($"{users.Username}#{users.Discriminator} ({users.Nickname})")); - } - - rolesDict.Add(roles.Position, node); - } - - foreach (var role in rolesDict) - { - userListTree.AddObject(role.Value); - } - - if (settings.EnableRichPresence) { - rpcClient.UpdateState($"In channel {client.GetGuild(currentSelectedGuild).GetTextChannel(currentSelectedChannel).Name}"); - rpcClient.UpdateStartTime(); - } - } catch { - await chatBoxList.SetSourceAsync(new List()); - } - }; - - messageBoxSend.Clicked += async () => - { - var restSharpClient = new RestClient("https://discord.com/api/v9"); - var restSharpReq = new RestRequest($"channels/{currentSelectedChannel}/messages"); - restSharpClient.AddDefaultHeader("Authorization", settings.Token); - restSharpReq.AddJsonBody(new { content = Encoding.UTF8.GetString(messageBoxText.Text.ToByteArray()) }); - - await restSharpClient.PostAsync>(restSharpReq); - - messageBoxText.Text = ""; - }; - - chatBoxList.OpenSelectedItem += args => - { - if (currentChannelMessages[args.Item].Split(" | ")[1].Contains("http")) - for (var i = 0; i < currentChannelMessages[args.Item].Split(" | ")[1].Split(" ").Count(); i++) - if (currentChannelMessages[args.Item].Split(" | ")[1].Split(" ")[i].Contains("http")) - { - var procStartInfo = new ProcessStartInfo("/bin/sh", - $"-c \"xdg-open {currentChannelMessages[args.Item].Split(" | ")[1].Split(" ")[i]}\"") - { - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true, - UseShellExecute = false - }; - - var proc = new Process(); - proc.StartInfo = procStartInfo; - proc.Start(); - } - }; - - Application.Top.KeyPress += async args => - { - switch (ShortcutHelper.GetModifiersKey(args.KeyEvent)) { - case Key.CtrlMask | Key.S: - serverListList.SetFocus(); - break; - case Key.CtrlMask | Key.C: - channelListTree.SetFocus(); - break; - case Key.CtrlMask | Key.AltMask | Key.C: - chatBoxList.SetFocus(); - break; - case Key.CtrlMask | Key.U: - userListTree.SetFocus(); - break; - case Key.CtrlMask | Key.Enter: - var restSharpClient = new RestClient("https://discord.com/api/v9"); - var restSharpReq = new RestRequest($"channels/{currentSelectedChannel}/messages"); - restSharpClient.AddDefaultHeader("Authorization", settings.Token); - restSharpReq.AddJsonBody(new { content = Encoding.UTF8.GetString(messageBoxText.Text.ToByteArray()) }); - - await restSharpClient.PostAsync>(restSharpReq); - - messageBoxText.Text = ""; - break; - } - }; - - window.RemoveAll(); - window.Add(serverList, channelList, messageBox, chatBox, userList); - serverList.Add(serverListList); - channelList.Add(channelListTree); - chatBox.Add(chatBoxList); - messageBox.Add(messageBoxText, messageBoxSend); - userList.Add(userListTree); - - return Task.CompletedTask; - }; - - client.MessageReceived += async msg => - { - if (msg.Channel.Id != currentSelectedChannel) return; - - var restSharpClient = new RestClient("https://discord.com/api/v9"); - var restSharpReq = new RestRequest($"channels/{currentSelectedChannel}/messages"); - restSharpReq.AddQueryParameter("limit", "1"); - restSharpClient.AddDefaultHeader("Authorization", settings.Token); - - var response = await restSharpClient.GetAsync>(restSharpReq); - - currentChannelMessages.Add( - $"{response.First().author.username}#{response.First().author.discriminator} | {response.First().content}"); - await chatBoxList.SetSourceAsync(currentChannelMessages); - - chatBoxList.ScrollDown(currentChannelMessages.Count - chatBoxList.Bounds.Height); - chatBoxList.SelectedItem = currentChannelMessages.Count - 1; - }; - - Application.MainLoop.AddTimeout(TimeSpan.FromMilliseconds(100), caller => { - if (settings.EnableRichPresence) - rpcClient.Invoke(); - return true; - }); - - Application.Top.Add(window, menuBar); - - Application.Run(); - Application.Shutdown(); - } catch (System.Exception err) { - Console.WriteLine(err); - } - } - - private Window buildChatBox(Window serverList) - { - return new Window("Chat Box") - { - X = Pos.Right(serverList), - Y = 0, - Width = Dim.Percent(60), - Height = Dim.Percent(90) - }; - } - - private Window buildChannelList(Window serverList) - { - return new Window("Channel List") - { - X = 0, - Y = Pos.Bottom(serverList), - Width = Dim.Percent(30), - Height = Dim.Percent(50) - }; - } - - private MenuBar buildMenu() - { - return new MenuBar(new[] - { - new MenuBarItem("File", new[] - { - new MenuItem("_Quit", "Quit the Application", () => { Application.Top.Running = false; }) - }), - new MenuBarItem("Help", new[] - { - new MenuItem("_License", "See the Application License", () => { - MessageBox.Query("License", "chord Copyright (C) 2021 Daryl Ronningen\nThis program comes with ABSOLUTELY NO WARRANTY; for details see section `15` of the GPL license\nThis is free software, and you are welcome to redistribute it under certain conditions; for details see section `2` of the GPL license", "Close"); - }) - }) - }); - } - - private Window buildMessageBox(Window serverList, Window chatBox) - { - return new Window("Message Box") - { - X = Pos.Right(serverList), - Y = Pos.Bottom(chatBox), - Width = Dim.Percent(60), - Height = Dim.Percent(10) - }; - } - - private Window buildUserList(Window chatBox) - { - return new Window("User List") - { - X = Pos.Right(chatBox), - Y = 0, - Width = Dim.Percent(10), - Height = Dim.Fill() - }; - } - - private Window buildServerList() - { - return new Window("Server List") - { - X = 0, - Y = 0, - Width = Dim.Percent(30), - Height = Dim.Percent(50) - }; - } - } -} - -public class Settings -{ - public string Token { get; set; } - public bool EnableRichPresence { get; set; } -} - -public class GetMessagesResponse -{ - public string content { get; set; } - public MessageAuthor author { get; set; } - public List embeds { get; set; } - public List attachments { get; set; } -} - -public class MessageAuthor -{ - public string username { get; set; } - public string discriminator { get; set; } -} - -public class MessageAttachments -{ - public string url { get; set; } -}