tgcli/telegram/Command.cs

308 lines
9.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using TdLib;
using static telegram.tgcli;
using static telegram.Util;
namespace telegram
{
public abstract class Command
{
public string ShortTrigger;
public string Shortcut;
public string Description;
public int ParamCount;
public abstract void Handler(List<string> inputParams);
protected Command(string shortTrigger, string shortcut, string description, int paramCount)
{
ShortTrigger = shortTrigger;
Shortcut = shortcut;
Description = description;
ParamCount = paramCount;
}
}
public static class CommandManager
{
public static List<Command> Commands = new List<Command>
{
new ClearCommand(),
new CloseCommand(),
new EditCommand(),
new HistoryCommand(),
new OpenCommand(),
new UnreadsCommand(),
new CloseUnreadCommand(),
new HelpCommand()
};
public static void HandleCommand(string input)
{
var split = input.Split(" ").ToList();
var trigger = split.First();
var command = Commands.Find(p => p.ShortTrigger == trigger || p.Shortcut == trigger);
if (command == null)
{
//TODO Console.WriteLine("do something");
return;
}
split.RemoveAt(0);
if (command.ParamCount == -1)
{
command.Handler(split);
}
else if (split.Count == command.ParamCount)
{
command.Handler(split);
}
else
{
//TODO Console.WriteLine("do something");
}
}
}
public class OpenCommand : Command
{
public OpenCommand() : base("o", "^O", "opens a chat", -1)
{
}
public override void Handler(List<string> inputParams)
{
var query = inputParams.Aggregate((current, param) => current + " " + param).Trim();
var chatId = SearchChatId(query);
if (chatId == 0) return;
currentChatId = 0;
currentChatUserId = 0;
currentUserRead = false;
var chat = GetChat(chatId);
if (chat.Type is TdApi.ChatType.ChatTypePrivate privChat)
{
currentChatUserId = privChat.UserId;
}
currentChatId = chat.Id;
prefix = $"[{chat.Title}";
lock (@lock)
{
messageQueue.Add($"{Ansi.Yellow}[tgcli] Opening chat: {chat.Title}");
messageQueue.Add($"{Ansi.Yellow}" + $"[tgcli] You have {chat.UnreadCount} unread message" +
$"{(chat.UnreadCount == 1 ? "." : "s.")}");
while (GetHistory(chatId, 50).Count == 1)
{
GetHistory(chatId, 10);
}
if (chat.UnreadCount >= 5)
{
var capped = chat.UnreadCount > 50;
GetHistory(chatId, capped ? 50 : chat.UnreadCount).ForEach(AddMessageToQueue);
if (capped)
messageQueue.Add(
$"{Ansi.Yellow}[tgcli] " + $"Showing 50 of {chat.UnreadCount} unread messages.");
}
else if (chat.UnreadCount > 0)
{
var unreads = GetHistory(chatId, chat.UnreadCount);
var rest = GetHistory(chatId, 5 - unreads.Count, unreads.First().Id);
rest.ForEach(AddMessageToQueue);
messageQueue.Add($"{Ansi.Yellow}[tgcli] ---UNREAD---");
unreads.ForEach(AddMessageToQueue);
}
else
{
GetHistory(chatId).ForEach(AddMessageToQueue);
}
}
var history = GetHistory(currentChatId, 50);
if (history.Count != 0)
MarkRead(chat.Id, history.First().Id);
var last = history.LastOrDefault(p => p.IsOutgoing);
if (last == null)
{
currentUserRead = true;
return;
}
lastMessage = last;
currentUserRead = IsMessageRead(last.ChatId, last.Id);
}
}
public class CloseUnreadCommand : Command
{
public CloseUnreadCommand() : base("cu", "", "closes a chat, marking it as unread", 0)
{
}
public override void Handler(List<string> inputParams)
{
if (currentChatId == 0) return; //TODO: do something
MarkUnread(currentChatId);
CommandManager.HandleCommand("close");
}
}
public class CloseCommand : Command
{
public CloseCommand() : base("c", "^E", "closes a chat", 0)
{
}
public override void Handler(List<string> inputParams)
{
if (currentChatId == 0) return; //TODO: do something
currentChatId = 0;
currentChatUserId = 0;
currentUserRead = false;
lastMessage = null;
prefix = "[tgcli";
lock (@lock)
{
messageQueue.Add($"{Ansi.Yellow}[tgcli] Closing chat.");
var count = missedMessages.Count;
if (count == 0) return;
messageQueue.Add($"{Ansi.Yellow}" + $"[tgcli] You have {count} missed message" +
$"{(count == 1 ? "." : "s.")}");
messageQueue.AddRange(missedMessages);
missedMessages.Clear();
}
}
}
public class HistoryCommand : Command
{
public HistoryCommand() : base("h", "", "shows chat history", -1)
{
}
public override void Handler(List<string> inputParams)
{
if (currentChatId == 0) return; //TODO: do something
var history = inputParams.Count == 1 && int.TryParse(inputParams[0], out var limit)
? GetHistory(currentChatId, limit)
: GetHistory(currentChatId);
lock (@lock)
{
messageQueue.Add($"{Ansi.Yellow}[tgcli] Last {history.Count} messages in " +
$"{GetChat(currentChatId).Title}");
}
foreach (var msg in history)
{
AddMessageToQueue(msg);
}
}
}
public class ClearCommand : Command
{
public ClearCommand() : base("cl", "^L", "clears console", 0)
{
}
public override void Handler(List<string> inputParams)
{
lock (@lock)
{
Console.Clear();
}
}
}
public class UnreadsCommand : Command
{
public UnreadsCommand() : base("u", "^U", "displays unread chat", -1)
{
}
public override void Handler(List<string> inputParams)
{
var unreads = GetUnreadChats(inputParams.Count == 1 && inputParams[0].Equals("all"));
lock (@lock)
{
messageQueue.Add($"{Ansi.Yellow}[tgcli] You have {unreads.Count} unread chats.");
unreads.ForEach(chat =>
{
string line;
if (chat.UnreadCount == 0)
line = $"{Ansi.Bold}{Ansi.Yellow}[M] {chat.Title}";
else
line = $"{Ansi.Bold}{Ansi.Green}[{chat.UnreadCount}] {chat.Title}";
messageQueue.Add(line);
});
}
}
}
public class HelpCommand : Command
{
public HelpCommand() : base("help", "", "lists all commands", 0)
{
}
public override void Handler(List<string> inputParams)
{
lock (@lock)
{
messageQueue.Add($"{Ansi.Yellow}[tgcli] Listing {CommandManager.Commands.Count} commands:");
CommandManager.Commands.ForEach(command =>
{
if (string.IsNullOrWhiteSpace(command.Shortcut))
{
messageQueue.Add($"{Ansi.Yellow}/{command.ShortTrigger}: {command.Description}");
return;
}
messageQueue.Add(
$"{Ansi.Yellow}/{command.ShortTrigger} [{command.Shortcut}]: {command.Description}");
});
}
}
}
public class EditCommand : Command
{
public EditCommand() : base("e", "", "edits last message", -1)
{
}
public override void Handler(List<string> inputParams)
{
var message = inputParams.Aggregate((current, param) => current + " " + param).Trim();
if (currentChatId == 0) return; //TODO do something
if (message.Length == 0)
{
currentInputLine = "/e " + ((TdApi.MessageContent.MessageText) lastMessage?.Content)?.Text?.Text;
return;
}
if (lastMessage == null)
{
//try to find last message
var history = GetHistory(currentChatId, 50);
var last = history.LastOrDefault(p => p.IsOutgoing);
if (last == null) return; //TODO do something
lastMessage = last;
}
if (string.IsNullOrWhiteSpace(message))
return;
EditMessage(message, lastMessage);
}
}
}