diff --git a/telegram/Command.cs b/telegram/Command.cs index 1eca999..743c289 100644 --- a/telegram/Command.cs +++ b/telegram/Command.cs @@ -39,11 +39,14 @@ namespace telegram new OpenCommand(), new UnreadsCommand(), new CloseUnreadCommand(), + new ListChatsCommand(), new ListSecretChatsCommand(), new OpenSecretCommand(), new OpenSecretDirectCommand(), new NewSecretChatCommand(), new CloseSecretChatCommand(), + new SearchUserCommand(), + new AddContactCommand(), new QuitCommand(), new HelpCommand(), new LogoutCommand(), @@ -476,6 +479,94 @@ namespace telegram } } + public class ListChatsCommand : Command + { + public ListChatsCommand() : base("lc", "", "lists all chats, optionally filtered", "[query]", -1) + { + } + + public override void Handler(List inputParams) + { + var chats = GetChats(); + + lock (@lock) + { + if (inputParams.Count > 0) + { + var query = inputParams.Aggregate((current, param) => current + " " + param).Trim(); + chats = chats.FindAll(p => p.Title.ToLower().Contains(query.ToLower())); + } + + messageQueue.Add($"{Ansi.Yellow}[tgcli] Listing {chats.Count} chats."); + chats.ForEach(chat => + { + string line; + if (chat.UnreadCount == 0) + line = $"{Ansi.Bold}{Ansi.Blue}[0] {chat.Title}"; + else + line = $"{Ansi.Bold}{Ansi.Green}[{chat.UnreadCount}] {chat.Title}"; + messageQueue.Add(line); + }); + } + } + } + + public class SearchUserCommand : Command + { + public SearchUserCommand() : base("su", "", "searches user globally", "", -1) + { + } + + public override void Handler(List inputParams) + { + if (inputParams.Count == 0) + return; //TODO do something + + var query = inputParams.Aggregate((current, param) => current + " " + param).Trim(); + + var chats = SearchChatsGlobal(query); + chats = chats.FindAll(p => p.Type is TdApi.ChatType.ChatTypePrivate); + + lock (@lock) + { + messageQueue.Add($"{Ansi.Yellow}[tgcli] Listing {chats.Count} chats."); + chats.ForEach(chat => + { + string line; + var type = (TdApi.ChatType.ChatTypePrivate) chat.Type; + var user = GetUser(type.UserId); + line = $"{Ansi.Bold}{Ansi.Yellow}@{user.Username} {Ansi.Magenta}{chat.Title}"; + messageQueue.Add(line); + }); + } + } + } + + public class AddContactCommand : Command + { + public AddContactCommand() : base("ac", "", "adds user to contact list", "", 1) + { + } + + public override void Handler(List inputParams) + { + var query = inputParams[0]; + + var chat = GetChatByUsernameGlobal(query); + + if (chat.Type is TdApi.ChatType.ChatTypePrivate type) + { + lock (@lock) + messageQueue.Add($"AddUserToContacts({type.UserId}, {chat.Title});"); + var user = SearchContacts("@" + GetUser(type.UserId).Username); + lock (@lock) + messageQueue.Add($"{user}"); + } + else + return; //TODO + } + } + public class ListSecretChatsCommand : Command { public ListSecretChatsCommand() : base("ls", "", "displays all open secret chats", "", 0) diff --git a/telegram/Util.cs b/telegram/Util.cs index 79e0398..0b706e9 100644 --- a/telegram/Util.cs +++ b/telegram/Util.cs @@ -147,6 +147,57 @@ namespace telegram .ToList(); } + public static List GetChats() + { + var response = client.ExecuteAsync(new GetChats + { + OffsetOrder = long.MaxValue, + Limit = int.MaxValue + }).Result; + return response.ChatIds.Select(GetChat).ToList(); + } + + public static List SearchChatsGlobal(string query) + { + if (query.TrimStart('@').Length < 5) + { + return new List(); + } + + var response = client.ExecuteAsync(new SearchPublicChats + { + Query = query + }).Result; + return response.ChatIds.Select(GetChat).ToList(); + } + + public static Chat GetChatByUsernameGlobal(string username) + { + var response = client.ExecuteAsync(new SearchPublicChat + { + Username = username + }).Result; + return response; + } + + public static void AddUserToContacts(int userId, string name) + { + //TODO this is broken + var response = client.ExecuteAsync(new ImportContacts + { + Contacts = new[] + { + new Contact + { + UserId = userId, + FirstName = name, + LastName = "", + PhoneNumber = "" + } + } + }).Result; + } + public static List GetSecretChats() { var response = client.ExecuteAsync(new GetChats @@ -305,7 +356,8 @@ namespace telegram if (query.StartsWith("@")) return results.ChatIds.First(p => - GetChat(p).Type is ChatType.ChatTypePrivate type && GetUser(type.UserId).Username == query.Substring(1)); + GetChat(p).Type is ChatType.ChatTypePrivate type && + GetUser(type.UserId).Username == query.Substring(1)); return results.ChatIds.First(); } catch @@ -326,9 +378,9 @@ namespace telegram Limit = 5 }).Result; - if (query.StartsWith("@")) - return results.UserIds.First(p => GetUser(p).Username == query.Substring(1)); - return results.UserIds.First(); + return query.StartsWith("@") + ? results.UserIds.First(p => GetUser(p).Username == query.Substring(1)) + : results.UserIds.First(); } catch { diff --git a/telegram/tgcli.cs b/telegram/tgcli.cs index 27ed15c..d5b0b05 100644 --- a/telegram/tgcli.cs +++ b/telegram/tgcli.cs @@ -14,14 +14,14 @@ namespace telegram { /* * TODO: - * waaay more error messages instead of just doing nothing or crashing (search for "do something") - * add option to disable terminal bell + * waaay more error messages instead of just doing nothing or crashing (search for TODOs and "do something") * command /sg -> search globally, some way to add contacts? - * command /sc -> search in chat list & list matching chats, archived, muted indicator * mute,unmute chats * photo & document download & show externally * publish AUR package - * maybe cursor input nav (cmd+del, left/right, up for last inputs, etc) + * cursor input nav (up/down history, (alt +) left/right) + * ref: http://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html#cursor-navigation + * ref: https://en.wikipedia.org/wiki/ANSI_escape_code#Escape_sequences * refactor everything */ @@ -41,11 +41,15 @@ namespace telegram public static volatile List messageQueue = new List(); public static volatile List missedMessages = new List(); public static volatile string prefix = "[tgcli"; + public static volatile bool silent = false; public static volatile object @lock = new object(); - private static void Main() + private static void Main(string[] args) { + if (args.Length == 1 && args[0] == "-s") + silent = true; + dbdir = $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}{Path.DirectorySeparatorChar}.tgcli"; if (!Directory.Exists(dbdir)) @@ -197,7 +201,7 @@ namespace telegram { ClearCurrentConsoleLine(); messageQueue.ForEach(p => Console.WriteLine(p + Ansi.ResetAll)); - if (messageQueue.Count > 0) + if (messageQueue.Count > 0 && !silent) Console.Write("\a"); //ring terminal bell messageQueue.Clear(); var status = GetFormattedStatus(currentUserRead);