Proper fix for #1
This commit is contained in:
parent
2133c73491
commit
82678907ba
|
@ -9,15 +9,17 @@ using static tgcli.tgcli;
|
|||
namespace tgcli {
|
||||
public class Util {
|
||||
public static class Ansi {
|
||||
public const string ResetAll = "\x1B[0m";
|
||||
public const string Red = "\x1b[31m";
|
||||
public const string Green = "\x1b[32m";
|
||||
public const string Yellow = "\x1b[33m";
|
||||
public const string Blue = "\x1b[34m";
|
||||
public const string Magenta = "\x1b[35m";
|
||||
public const string Cyan = "\x1b[36m";
|
||||
public const string Bold = "\x1b[1m";
|
||||
public const string BoldOff = "\x1b[22m";
|
||||
public const string ResetAll = "\x1B[0m";
|
||||
public const string Red = "\x1b[31m";
|
||||
public const string Green = "\x1b[32m";
|
||||
public const string Yellow = "\x1b[33m";
|
||||
public const string Blue = "\x1b[34m";
|
||||
public const string Magenta = "\x1b[35m";
|
||||
public const string Cyan = "\x1b[36m";
|
||||
public const string Bold = "\x1b[1m";
|
||||
public const string BoldOff = "\x1b[22m";
|
||||
public const string Inverse = "\x1b[7m";
|
||||
public const string InverseOff = "\x1b[27m";
|
||||
}
|
||||
|
||||
public static User GetUser(long uid) {
|
||||
|
@ -350,7 +352,10 @@ namespace tgcli {
|
|||
input = input.Replace(Ansi.Magenta, "");
|
||||
input = input.Replace(Ansi.Red, "");
|
||||
input = input.Replace(Ansi.Yellow, "");
|
||||
input = input.Replace(Ansi.Bold, "");
|
||||
input = input.Replace(Ansi.BoldOff, "");
|
||||
input = input.Replace(Ansi.Inverse, "");
|
||||
input = input.Replace(Ansi.InverseOff, "");
|
||||
input = input.Replace(Ansi.ResetAll, "");
|
||||
return input.Length;
|
||||
}
|
||||
|
@ -361,18 +366,46 @@ namespace tgcli {
|
|||
return output + $"{Ansi.ResetAll}]";
|
||||
}
|
||||
|
||||
public static string TruncateString(string input, int maxLen) {
|
||||
public static string TruncateString(string input, int maxLen, string truncateMarker = "~") {
|
||||
if (maxLen < 2)
|
||||
maxLen = 2;
|
||||
return input.Length <= maxLen ? input : input.Substring(0, maxLen - 1) + "~";
|
||||
return input.Length <= maxLen ? input : input.Substring(0, maxLen - 1) + truncateMarker;
|
||||
}
|
||||
|
||||
public static string TruncateMessageStart(string input, int maxLen) {
|
||||
if (maxLen < 2)
|
||||
maxLen = 2;
|
||||
if (input.Contains("⏎ "))
|
||||
input = "⏎ " + input.Split("⏎ ").Last();
|
||||
return input.Length < maxLen ? input : "<" + input.Substring(input.Length - maxLen + 2);
|
||||
public static (string messageBuffer, int relativeCursorPosition) GetViewIntoMessageBuffer(string message, int absoluteCursorPosition, int bufferWidth) {
|
||||
const int wraparoundOffsetPre = 2; // number of "untouchable" characters moving the cursor onto will cause a wrap on the right screen edge
|
||||
const int wraparoundOffsetPost = 5; // number of "untouchable" characters moving the cursor onto will cause a wrap on the left screen edge
|
||||
|
||||
const int wraparoundOffsetPreW = wraparoundOffsetPre + 1; // offset + 1 (character on the edge), for easier calculations
|
||||
const int wraparoundOffsetPostW = wraparoundOffsetPost + 1; // offset + 1 (character on the edge), for easier calculations
|
||||
|
||||
if (absoluteCursorPosition > message.Length)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
if (message.Length < bufferWidth)
|
||||
return (message, absoluteCursorPosition);
|
||||
|
||||
if (absoluteCursorPosition < bufferWidth - wraparoundOffsetPre - 1)
|
||||
return (TruncateString(message, bufferWidth, $"{Ansi.Inverse}>{Ansi.InverseOff}"), absoluteCursorPosition);
|
||||
|
||||
// now we can be sure the message needs at least one wrap
|
||||
|
||||
// first wrap
|
||||
// get rid of the content shown on the zeroth wrap, which is buf width minus wraparoundPreW (respects > character on screen edge)
|
||||
var finalMessage = message[(bufferWidth - wraparoundOffsetPreW - wraparoundOffsetPost)..];
|
||||
var finalCursorPos = absoluteCursorPosition - bufferWidth + wraparoundOffsetPreW + wraparoundOffsetPostW;
|
||||
|
||||
// successive wraps
|
||||
// repeat above steps (but respective of the new < character) until the string fits into the buffer
|
||||
// it fits into the buffer when cursorPos >= bufferwidth minus wraparound (this time respecting > character absent on first wrap)
|
||||
while (finalCursorPos >= bufferWidth - wraparoundOffsetPreW) {
|
||||
finalMessage = finalMessage[(bufferWidth - wraparoundOffsetPreW - wraparoundOffsetPostW)..];
|
||||
finalCursorPos = finalCursorPos - bufferWidth + wraparoundOffsetPreW + wraparoundOffsetPostW;
|
||||
}
|
||||
|
||||
finalMessage = TruncateString(finalMessage, bufferWidth - 1, $"{Ansi.Inverse}>{Ansi.InverseOff}");
|
||||
|
||||
return ($"{Ansi.Inverse}<{Ansi.InverseOff}" + finalMessage, finalCursorPos);
|
||||
}
|
||||
|
||||
public static readonly List<Tuple<string, string>> Emojis = new() {
|
||||
|
|
|
@ -190,7 +190,8 @@ namespace tgcli {
|
|||
output += "]";
|
||||
output += " > ";
|
||||
var prefixlen = GetActualStringWidth(output);
|
||||
output += TruncateMessageStart(currentInputLine, Console.LargestWindowWidth - GetActualStringWidth(output));
|
||||
var inputLine = GetViewIntoMessageBuffer(currentInputLine, currentInputPos, Console.LargestWindowWidth - prefixlen);
|
||||
output += inputLine.messageBuffer;
|
||||
|
||||
ClearCurrentConsoleLine();
|
||||
messageQueue.ForEach(p => Console.WriteLine(p + Ansi.ResetAll));
|
||||
|
@ -198,7 +199,7 @@ namespace tgcli {
|
|||
Console.Write("\a"); //ring terminal bell
|
||||
messageQueue.Clear();
|
||||
Console.Write(output);
|
||||
Console.Write($"\u001b[{Math.Min(currentInputPos + prefixlen + 1, Console.LargestWindowWidth)}G");
|
||||
Console.Write($"\u001b[{inputLine.relativeCursorPosition + prefixlen + 1}G");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,7 +451,7 @@ namespace tgcli {
|
|||
}
|
||||
|
||||
var rest = $"{text}{(msg.EditDate == 0 ? "" : $"{Ansi.Yellow}*")}";
|
||||
|
||||
|
||||
if (msg.InteractionInfo != null && msg.InteractionInfo.Reactions.Any(p => p.Type is ReactionType.ReactionTypeEmoji)) {
|
||||
rest = $"{rest} {Ansi.Cyan}<--";
|
||||
foreach (var reaction in msg.InteractionInfo.Reactions)
|
||||
|
@ -524,11 +525,11 @@ namespace tgcli {
|
|||
+ $"{text}"
|
||||
+ $"{Ansi.Yellow}*";
|
||||
}
|
||||
|
||||
|
||||
private static string FormatMessage(Update.UpdateMessageUnreadReactions msg) {
|
||||
string text;
|
||||
|
||||
var message = GetMessage(msg.ChatId, msg.MessageId);
|
||||
var message = GetMessage(msg.ChatId, msg.MessageId);
|
||||
if (message.Content is MessageContent.MessageText messageText)
|
||||
text = messageText.Text.Text;
|
||||
else
|
||||
|
@ -590,12 +591,12 @@ namespace tgcli {
|
|||
messageQueue.Add(formattedMessage);
|
||||
ScreenUpdate();
|
||||
}
|
||||
|
||||
|
||||
public static void AddMessageToQueue(Update.UpdateMessageUnreadReactions msg) {
|
||||
//handle muted
|
||||
if (IsMuted(GetChat(msg.ChatId)) && currentChatId != msg.ChatId)
|
||||
return;
|
||||
|
||||
|
||||
if (!msg.UnreadReactions.Any(p => p.Type is ReactionType.ReactionTypeEmoji))
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in a new issue