feat: render relative timestamps the way Discord does it

This commit is contained in:
Oliver Booth 2023-08-27 21:44:56 +01:00
parent f3d035d67b
commit 2cb98e85c7
Signed by: oliverbooth
GPG Key ID: B89D139977693FED
1 changed files with 50 additions and 2 deletions

View File

@ -1,5 +1,4 @@
using Cysharp.Text;
using Humanizer;
namespace VPLink.Common.Data;
@ -40,7 +39,7 @@ public struct PlainTextMessageBuilder : IDisposable
switch (format)
{
case TimestampFormat.Relative:
AddWord(timestamp.Humanize(), whitespace);
AddWord(FormatRelativeTime(timestamp), whitespace);
break;
case TimestampFormat.None:
@ -103,4 +102,53 @@ public struct PlainTextMessageBuilder : IDisposable
{
return _builder.ToString().Trim();
}
private static string FormatRelativeTime(DateTimeOffset targetTime)
{
TimeSpan timeDifference = DateTimeOffset.Now - targetTime;
bool isFuture = timeDifference.TotalMilliseconds < 0;
int value;
string unit;
timeDifference = TimeSpan.FromMilliseconds(Math.Abs(timeDifference.TotalMilliseconds));
switch (timeDifference.TotalDays)
{
case >= 365:
unit = "year";
value = (int)(timeDifference.TotalDays / 365);
break;
case >= 30:
unit = "month";
value = (int)(timeDifference.TotalDays / 30);
break;
case >= 1:
unit = "day";
value = (int)timeDifference.TotalDays;
break;
default:
if (timeDifference.TotalHours >= 1)
{
unit = "hour";
value = (int)timeDifference.TotalHours;
}
else if (timeDifference.TotalMinutes >= 1)
{
unit = "minute";
value = (int)timeDifference.TotalMinutes;
}
else
{
unit = "second";
value = (int)timeDifference.TotalSeconds;
}
break;
}
string suffix = value > 1 ? "s" : "";
return isFuture ? $"in {value} {unit}{suffix}" : $"{value} {unit}{suffix} ago";
}
}