diff --git a/locale/Messages.resx b/locale/Messages.resx index 7b9a471..cf6f89d 100644 --- a/locale/Messages.resx +++ b/locale/Messages.resx @@ -654,4 +654,10 @@ Your random number is: + + Timestamp for {0}: + + + Offset: {0} + diff --git a/locale/Messages.ru.resx b/locale/Messages.ru.resx index 8489a45..aff4dd3 100644 --- a/locale/Messages.ru.resx +++ b/locale/Messages.ru.resx @@ -654,4 +654,10 @@ Ваше случайное число: + + Временная метка для {0}: + + + Офсет: {0} + diff --git a/locale/Messages.tt-ru.resx b/locale/Messages.tt-ru.resx index df98622..7c65929 100644 --- a/locale/Messages.tt-ru.resx +++ b/locale/Messages.tt-ru.resx @@ -654,4 +654,10 @@ ваше рандомное число: + + таймштамп для {0}: + + + офсет: {0} + diff --git a/src/Commands/ToolsCommandGroup.cs b/src/Commands/ToolsCommandGroup.cs index 64e6729..6abb918 100644 --- a/src/Commands/ToolsCommandGroup.cs +++ b/src/Commands/ToolsCommandGroup.cs @@ -19,7 +19,7 @@ using Remora.Results; namespace Octobot.Commands; /// -/// Handles tool commands: /showinfo, /random. +/// Handles tool commands: /showinfo, /random, /timestamp. /// [UsedImplicitly] public class ToolsCommandGroup : CommandGroup @@ -289,4 +289,74 @@ public class ToolsCommandGroup : CommandGroup return await _feedback.SendContextualEmbedResultAsync(embed, ct); } + + private static readonly TimestampStyle[] AllStyles = + { + TimestampStyle.ShortDate, + TimestampStyle.LongDate, + TimestampStyle.ShortTime, + TimestampStyle.LongTime, + TimestampStyle.ShortDateTime, + TimestampStyle.LongDateTime, + TimestampStyle.RelativeTime + }; + + /// + /// A slash command that shows the current timestamp with an optional offset in all styles supported by Discord. + /// + /// The offset for the current timestamp. + /// + /// A feedback sending result which may or may not have succeeded. + /// + [Command("timestamp")] + [DiscordDefaultDMPermission(false)] + [Description("Shows a timestamp in all styles")] + [UsedImplicitly] + public async Task ExecuteTimestampAsync( + [Description("Offset from current time")] + TimeSpan? offset = null) + { + if (!_context.TryGetContextIDs(out var guildId, out _, out var userId)) + { + return new ArgumentInvalidError(nameof(_context), "Unable to retrieve necessary IDs from command context"); + } + + var userResult = await _userApi.GetUserAsync(userId, CancellationToken); + if (!userResult.IsDefined(out var user)) + { + return Result.FromError(userResult); + } + + var data = await _guildData.GetData(guildId, CancellationToken); + Messages.Culture = GuildSettings.Language.Get(data.Settings); + + return await SendTimestampAsync(offset, user, CancellationToken); + } + + private async Task SendTimestampAsync(TimeSpan? offset, IUser user, CancellationToken ct) + { + var timestamp = DateTimeOffset.UtcNow.Add(offset ?? TimeSpan.Zero).ToUnixTimeSeconds(); + + var description = new StringBuilder().Append("# ").AppendLine(timestamp.ToString()); + + if (offset is not null) + { + description.AppendLine(string.Format( + Messages.TimestampOffset, Markdown.InlineCode(offset.ToString() ?? string.Empty))).AppendLine(); + } + + foreach (var markdownTimestamp in AllStyles.Select(style => Markdown.Timestamp(timestamp, style))) + { + description.Append("- ").Append(Markdown.InlineCode(markdownTimestamp)) + .Append(" → ").AppendLine(markdownTimestamp); + } + + var embed = new EmbedBuilder().WithSmallTitle( + string.Format(Messages.TimestampTitle, user.GetTag()), user) + .WithDescription(description.ToString()) + .WithColour(ColorsList.Blue) + .Build(); + + return await _feedback.SendContextualEmbedResultAsync(embed, ct); + } } diff --git a/src/Messages.Designer.cs b/src/Messages.Designer.cs index 3c2c747..549a681 100644 --- a/src/Messages.Designer.cs +++ b/src/Messages.Designer.cs @@ -1135,5 +1135,21 @@ namespace Octobot { return ResourceManager.GetString("RandomOutput", resourceCulture); } } + + internal static string TimestampTitle + { + get + { + return ResourceManager.GetString("TimestampTitle", resourceCulture); + } + } + + internal static string TimestampOffset + { + get + { + return ResourceManager.GetString("TimestampOffset", resourceCulture); + } + } } }