diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index c08fa4d..b697dac 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -23,9 +23,9 @@ jobs: uses: actions/checkout@v4 - name: ReSharper CLI InspectCode - uses: muno92/resharper_inspectcode@1.11.0 + uses: muno92/resharper_inspectcode@1.11.1 with: solutionPath: ./Octobot.sln - ignoreIssueType: InvertIf, ConvertIfStatementToSwitchStatement + ignoreIssueType: InvertIf, ConvertIfStatementToSwitchStatement, ConvertToPrimaryConstructor extensions: ReSharperPlugin.CognitiveComplexity solutionWideAnalysis: true diff --git a/Octobot.csproj b/Octobot.csproj index 92f4755..7d3500b 100644 --- a/Octobot.csproj +++ b/Octobot.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 enable enable 2.0.0 @@ -16,6 +16,7 @@ LabsDevelopment en A general-purpose Discord bot for moderation written in C# + docs/octobot.ico diff --git a/docs/octobot.ico b/docs/octobot.ico new file mode 100644 index 0000000..147b716 Binary files /dev/null and b/docs/octobot.ico differ diff --git a/locale/Messages.resx b/locale/Messages.resx index a9367f7..f145ab2 100644 --- a/locale/Messages.resx +++ b/locale/Messages.resx @@ -348,8 +348,8 @@ The event will start at {0} until {1} in {2} - - Event details + + Open Event Info The event has lasted for `{0}` diff --git a/locale/Messages.ru.resx b/locale/Messages.ru.resx index d0cbd79..5b97eda 100644 --- a/locale/Messages.ru.resx +++ b/locale/Messages.ru.resx @@ -345,8 +345,8 @@ Событие пройдёт с {0} до {1} в {2} - - Подробнее о событии + + Открыть сведения о событии Событие длилось `{0}` diff --git a/locale/Messages.tt-ru.resx b/locale/Messages.tt-ru.resx index 3bed232..2761827 100644 --- a/locale/Messages.tt-ru.resx +++ b/locale/Messages.tt-ru.resx @@ -348,8 +348,8 @@ движуха будет происходить с {0} до {1} в {2} - - побольше о движухе + + открыть ивент все это длилось `{0}` diff --git a/src/Commands/AboutCommandGroup.cs b/src/Commands/AboutCommandGroup.cs index ff58b66..e491470 100644 --- a/src/Commands/AboutCommandGroup.cs +++ b/src/Commands/AboutCommandGroup.cs @@ -88,7 +88,7 @@ public class AboutCommandGroup : CommandGroup guildId, dev.Id, ct); var tag = guildMemberResult.IsSuccess ? $"<@{dev.Id}>" : $"@{dev.Username}"; - builder.AppendLine($"- {tag} — {$"AboutDeveloper@{dev.Username}".Localized()}"); + builder.AppendBulletPointLine($"{tag} — {$"AboutDeveloper@{dev.Username}".Localized()}"); } builder.Append($"### [{Messages.AboutTitleRepository}](https://github.com/LabsDevelopment/Octobot)"); diff --git a/src/Commands/BanCommandGroup.cs b/src/Commands/BanCommandGroup.cs index 575e709..3f89819 100644 --- a/src/Commands/BanCommandGroup.cs +++ b/src/Commands/BanCommandGroup.cs @@ -135,11 +135,10 @@ public class BanCommandGroup : CommandGroup return await _feedback.SendContextualEmbedResultAsync(errorEmbed, ct); } - var builder = new StringBuilder().Append("- ") - .AppendLine(string.Format(Messages.DescriptionActionReason, reason)); + var builder = new StringBuilder().AppendBulletPointLine(string.Format(Messages.DescriptionActionReason, reason)); if (duration is not null) { - builder.Append("- ").Append( + builder.AppendBulletPoint( string.Format( Messages.DescriptionActionExpiresAt, Markdown.Timestamp(DateTimeOffset.UtcNow.Add(duration.Value)))); @@ -274,8 +273,7 @@ public class BanCommandGroup : CommandGroup .WithColour(ColorsList.Green).Build(); var title = string.Format(Messages.UserUnbanned, target.GetTag()); - var description = new StringBuilder().Append("- ") - .Append(string.Format(Messages.DescriptionActionReason, reason)); + var description = new StringBuilder().AppendBulletPoint(string.Format(Messages.DescriptionActionReason, reason)); var logResult = _utility.LogActionAsync( data.Settings, channelId, executor, title, description.ToString(), target, ColorsList.Green, ct: ct); if (!logResult.IsSuccess) diff --git a/src/Commands/KickCommandGroup.cs b/src/Commands/KickCommandGroup.cs index 25fe1b5..f2a840d 100644 --- a/src/Commands/KickCommandGroup.cs +++ b/src/Commands/KickCommandGroup.cs @@ -134,7 +134,7 @@ public class KickCommandGroup : CommandGroup { var dmEmbed = new EmbedBuilder().WithGuildTitle(guild) .WithTitle(Messages.YouWereKicked) - .WithDescription($"- {string.Format(Messages.DescriptionActionReason, reason)}") + .WithDescription(MarkdownExtensions.BulletPoint(string.Format(Messages.DescriptionActionReason, reason))) .WithActionFooter(executor) .WithCurrentTimestamp() .WithColour(ColorsList.Red) @@ -159,7 +159,7 @@ public class KickCommandGroup : CommandGroup data.GetOrCreateMemberData(target.ID).Roles.Clear(); var title = string.Format(Messages.UserKicked, target.GetTag()); - var description = $"- {string.Format(Messages.DescriptionActionReason, reason)}"; + var description = MarkdownExtensions.BulletPoint(string.Format(Messages.DescriptionActionReason, reason)); var logResult = _utility.LogActionAsync( data.Settings, channelId, executor, title, description, target, ColorsList.Red, ct: ct); if (!logResult.IsSuccess) diff --git a/src/Commands/MuteCommandGroup.cs b/src/Commands/MuteCommandGroup.cs index e431a53..2ce06ae 100644 --- a/src/Commands/MuteCommandGroup.cs +++ b/src/Commands/MuteCommandGroup.cs @@ -136,8 +136,8 @@ public class MuteCommandGroup : CommandGroup } var title = string.Format(Messages.UserMuted, target.GetTag()); - var description = new StringBuilder().Append("- ").AppendLine(string.Format(Messages.DescriptionActionReason, reason)) - .Append("- ").Append(string.Format( + var description = new StringBuilder().AppendBulletPointLine(string.Format(Messages.DescriptionActionReason, reason)) + .AppendBulletPoint(string.Format( Messages.DescriptionActionExpiresAt, Markdown.Timestamp(until))).ToString(); var logResult = _utility.LogActionAsync( @@ -325,7 +325,7 @@ public class MuteCommandGroup : CommandGroup } var title = string.Format(Messages.UserUnmuted, target.GetTag()); - var description = $"- {string.Format(Messages.DescriptionActionReason, reason)}"; + var description = MarkdownExtensions.BulletPoint(string.Format(Messages.DescriptionActionReason, reason)); var logResult = _utility.LogActionAsync( data.Settings, channelId, executor, title, description, target, ColorsList.Green, ct: ct); if (!logResult.IsSuccess) diff --git a/src/Commands/RemindCommandGroup.cs b/src/Commands/RemindCommandGroup.cs index 6e4d31b..79a583b 100644 --- a/src/Commands/RemindCommandGroup.cs +++ b/src/Commands/RemindCommandGroup.cs @@ -75,7 +75,7 @@ public class RemindCommandGroup : CommandGroup return await ListRemindersAsync(data.GetOrCreateMemberData(executorId), executor, bot, CancellationToken); } - private async Task ListRemindersAsync(MemberData data, IUser executor, IUser bot, CancellationToken ct) + private Task ListRemindersAsync(MemberData data, IUser executor, IUser bot, CancellationToken ct) { if (data.Reminders.Count == 0) { @@ -83,17 +83,16 @@ public class RemindCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); } var builder = new StringBuilder(); for (var i = 0; i < data.Reminders.Count; i++) { var reminder = data.Reminders[i]; - builder.Append("- ").AppendLine(string.Format(Messages.ReminderPosition, Markdown.InlineCode((i + 1).ToString()))) - .Append(" - ").AppendLine(string.Format(Messages.ReminderText, Markdown.InlineCode(reminder.Text))) - .Append(" - ") - .AppendLine(string.Format(Messages.ReminderTime, Markdown.Timestamp(reminder.At))); + builder.AppendBulletPointLine(string.Format(Messages.ReminderPosition, Markdown.InlineCode((i + 1).ToString()))) + .AppendSubBulletPointLine(string.Format(Messages.ReminderText, Markdown.InlineCode(reminder.Text))) + .AppendSubBulletPointLine(string.Format(Messages.ReminderTime, Markdown.Timestamp(reminder.At))); } var embed = new EmbedBuilder().WithSmallTitle( @@ -102,7 +101,7 @@ public class RemindCommandGroup : CommandGroup .WithColour(ColorsList.Cyan) .Build(); - return await _feedback.SendContextualEmbedResultAsync( + return _feedback.SendContextualEmbedResultAsync( embed, ct); } @@ -140,7 +139,7 @@ public class RemindCommandGroup : CommandGroup return await AddReminderAsync(@in, text, data, channelId, executor, CancellationToken); } - private async Task AddReminderAsync( + private Task AddReminderAsync( TimeSpan @in, string text, GuildData data, Snowflake channelId, IUser executor, CancellationToken ct = default) { @@ -155,9 +154,9 @@ public class RemindCommandGroup : CommandGroup Text = text }); - var builder = new StringBuilder().Append("- ").AppendLine(string.Format( + var builder = new StringBuilder().AppendBulletPointLine(string.Format( Messages.ReminderText, Markdown.InlineCode(text))) - .Append("- ").Append(string.Format(Messages.ReminderTime, Markdown.Timestamp(remindAt))); + .AppendBulletPoint(string.Format(Messages.ReminderTime, Markdown.Timestamp(remindAt))); var embed = new EmbedBuilder().WithSmallTitle( string.Format(Messages.ReminderCreated, executor.GetTag()), executor) @@ -166,7 +165,7 @@ public class RemindCommandGroup : CommandGroup .WithFooter(string.Format(Messages.ReminderPosition, memberData.Reminders.Count)) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct); } /// @@ -200,7 +199,7 @@ public class RemindCommandGroup : CommandGroup return await DeleteReminderAsync(data.GetOrCreateMemberData(executorId), position - 1, bot, CancellationToken); } - private async Task DeleteReminderAsync(MemberData data, int index, IUser bot, + private Task DeleteReminderAsync(MemberData data, int index, IUser bot, CancellationToken ct) { if (index >= data.Reminders.Count) @@ -209,14 +208,14 @@ public class RemindCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); } var reminder = data.Reminders[index]; var description = new StringBuilder() - .Append("- ").AppendLine(string.Format(Messages.ReminderText, Markdown.InlineCode(reminder.Text))) - .Append("- ").AppendLine(string.Format(Messages.ReminderTime, Markdown.Timestamp(reminder.At))); + .AppendBulletPointLine(string.Format(Messages.ReminderText, Markdown.InlineCode(reminder.Text))) + .AppendBulletPointLine(string.Format(Messages.ReminderTime, Markdown.Timestamp(reminder.At))); data.Reminders.RemoveAt(index); @@ -225,7 +224,7 @@ public class RemindCommandGroup : CommandGroup .WithColour(ColorsList.Green) .Build(); - return await _feedback.SendContextualEmbedResultAsync( + return _feedback.SendContextualEmbedResultAsync( embed, ct); } } diff --git a/src/Commands/SettingsCommandGroup.cs b/src/Commands/SettingsCommandGroup.cs index 2c114c1..60323d7 100644 --- a/src/Commands/SettingsCommandGroup.cs +++ b/src/Commands/SettingsCommandGroup.cs @@ -105,7 +105,7 @@ public class SettingsCommandGroup : CommandGroup return await SendSettingsListAsync(cfg, bot, page, CancellationToken); } - private async Task SendSettingsListAsync(JsonNode cfg, IUser bot, int page, + private Task SendSettingsListAsync(JsonNode cfg, IUser bot, int page, CancellationToken ct = default) { var description = new StringBuilder(); @@ -124,7 +124,7 @@ public class SettingsCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - return await _feedback.SendContextualEmbedResultAsync(errorEmbed, ct); + return _feedback.SendContextualEmbedResultAsync(errorEmbed, ct); } footer.Append($"{Messages.Page} {page}/{totalPages} "); @@ -138,9 +138,9 @@ public class SettingsCommandGroup : CommandGroup var optionName = AllOptions[i].Name; var optionValue = AllOptions[i].Display(cfg); - description.AppendLine($"- {$"Settings{optionName}".Localized()}") - .Append($" - {Markdown.InlineCode(optionName)}: ") - .AppendLine(optionValue); + description.AppendBulletPointLine($"Settings{optionName}".Localized()) + .AppendSubBulletPoint(Markdown.InlineCode(optionName)) + .Append(": ").AppendLine(optionValue); } var embed = new EmbedBuilder().WithSmallTitle(Messages.SettingsListTitle, bot) @@ -149,7 +149,7 @@ public class SettingsCommandGroup : CommandGroup .WithFooter(footer.ToString()) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct); } /// diff --git a/src/Commands/ToolsCommandGroup.cs b/src/Commands/ToolsCommandGroup.cs index c0b99f5..be4c2c1 100644 --- a/src/Commands/ToolsCommandGroup.cs +++ b/src/Commands/ToolsCommandGroup.cs @@ -102,11 +102,11 @@ public class ToolsCommandGroup : CommandGroup if (target.GlobalName is not null) { - builder.Append("- ").AppendLine(Messages.UserInfoDisplayName) + builder.AppendBulletPointLine(Messages.UserInfoDisplayName) .AppendLine(Markdown.InlineCode(target.GlobalName)); } - builder.Append("- ").AppendLine(Messages.UserInfoDiscordUserSince) + builder.AppendBulletPointLine(Messages.UserInfoDiscordUserSince) .AppendLine(Markdown.Timestamp(target.ID.Timestamp)); var memberData = data.GetOrCreateMemberData(target.ID); @@ -170,23 +170,23 @@ public class ToolsCommandGroup : CommandGroup { if (guildMember.Nickname.IsDefined(out var nickname)) { - builder.Append("- ").AppendLine(Messages.UserInfoGuildNickname) + builder.AppendBulletPointLine(Messages.UserInfoGuildNickname) .AppendLine(Markdown.InlineCode(nickname)); } - builder.Append("- ").AppendLine(Messages.UserInfoGuildMemberSince) + builder.AppendBulletPointLine(Messages.UserInfoGuildMemberSince) .AppendLine(Markdown.Timestamp(guildMember.JoinedAt)); if (guildMember.PremiumSince.IsDefined(out var premiumSince)) { - builder.Append("- ").AppendLine(Messages.UserInfoGuildMemberPremiumSince) + builder.AppendBulletPointLine(Messages.UserInfoGuildMemberPremiumSince) .AppendLine(Markdown.Timestamp(premiumSince.Value)); color = ColorsList.Magenta; } if (guildMember.Roles.Count > 0) { - builder.Append("- ").AppendLine(Messages.UserInfoGuildRoles); + builder.AppendBulletPointLine(Messages.UserInfoGuildRoles); for (var i = 0; i < guildMember.Roles.Count - 1; i++) { builder.Append($"<@&{guildMember.Roles[i]}>, "); @@ -202,30 +202,30 @@ public class ToolsCommandGroup : CommandGroup { if (memberData.BannedUntil < DateTimeOffset.MaxValue) { - builder.Append("- ").AppendLine(Messages.UserInfoBanned) - .Append(" - ").AppendLine(string.Format( + builder.AppendBulletPointLine(Messages.UserInfoBanned) + .AppendSubBulletPointLine(string.Format( Messages.DescriptionActionExpiresAt, Markdown.Timestamp(memberData.BannedUntil.Value))); return; } - builder.Append("- ").AppendLine(Messages.UserInfoBannedPermanently); + builder.AppendBulletPointLine(Messages.UserInfoBannedPermanently); } private static void AppendMuteInformation( MemberData memberData, DateTimeOffset? communicationDisabledUntil, StringBuilder builder) { - builder.Append("- ").AppendLine(Messages.UserInfoMuted); + builder.AppendBulletPointLine(Messages.UserInfoMuted); if (memberData.MutedUntil is not null && DateTimeOffset.UtcNow <= memberData.MutedUntil) { - builder.Append(" - ").AppendLine(Messages.UserInfoMutedByMuteRole) - .Append(" - ").AppendLine(string.Format( + builder.AppendSubBulletPointLine(Messages.UserInfoMutedByMuteRole) + .AppendSubBulletPointLine(string.Format( Messages.DescriptionActionExpiresAt, Markdown.Timestamp(memberData.MutedUntil.Value))); } if (communicationDisabledUntil is not null) { - builder.Append(" - ").AppendLine(Messages.UserInfoMutedByTimeout) - .Append(" - ").AppendLine(string.Format( + builder.AppendSubBulletPointLine(Messages.UserInfoMutedByTimeout) + .AppendSubBulletPointLine(string.Format( Messages.DescriptionActionExpiresAt, Markdown.Timestamp(communicationDisabledUntil.Value))); } } @@ -276,19 +276,19 @@ public class ToolsCommandGroup : CommandGroup return await ShowGuildInfoAsync(bot, guild, CancellationToken); } - private async Task ShowGuildInfoAsync(IUser bot, IGuild guild, CancellationToken ct) + private Task ShowGuildInfoAsync(IUser bot, IGuild guild, CancellationToken ct) { var description = new StringBuilder().AppendLine($"## {guild.Name}"); if (guild.Description is not null) { - description.Append("- ").AppendLine(Messages.GuildInfoDescription) + description.AppendBulletPointLine(Messages.GuildInfoDescription) .AppendLine(Markdown.InlineCode(guild.Description)); } - description.Append("- ").AppendLine(Messages.GuildInfoCreatedAt) + description.AppendBulletPointLine(Messages.GuildInfoCreatedAt) .AppendLine(Markdown.Timestamp(guild.ID.Timestamp)) - .Append("- ").AppendLine(Messages.GuildInfoOwner) + .AppendBulletPointLine(Messages.GuildInfoOwner) .AppendLine(Mention.User(guild.OwnerID)); var embedColor = ColorsList.Cyan; @@ -296,9 +296,9 @@ public class ToolsCommandGroup : CommandGroup if (guild.PremiumTier > PremiumTier.None) { description.Append("### ").AppendLine(Messages.GuildInfoServerBoost) - .Append("- ").Append(Messages.GuildInfoBoostTier) + .AppendBulletPoint(Messages.GuildInfoBoostTier) .Append(": ").AppendLine(Markdown.InlineCode(guild.PremiumTier.ToString())) - .Append("- ").Append(Messages.GuildInfoBoostCount) + .AppendBulletPoint(Messages.GuildInfoBoostCount) .Append(": ").AppendLine(Markdown.InlineCode(guild.PremiumSubscriptionCount.ToString())); embedColor = ColorsList.Magenta; } @@ -312,7 +312,7 @@ public class ToolsCommandGroup : CommandGroup .WithFooter($"ID: {guild.ID.ToString()}") .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct); } /// @@ -349,7 +349,7 @@ public class ToolsCommandGroup : CommandGroup return await SendRandomNumberAsync(first, second, executor, CancellationToken); } - private async Task SendRandomNumberAsync(long first, long? secondNullable, + private Task SendRandomNumberAsync(long first, long? secondNullable, IUser executor, CancellationToken ct) { const long secondDefault = 0; @@ -362,14 +362,14 @@ public class ToolsCommandGroup : CommandGroup var description = new StringBuilder().Append("# ").Append(i); - description.AppendLine().Append("- ").Append(string.Format( + description.AppendLine().AppendBulletPoint(string.Format( Messages.RandomMin, Markdown.InlineCode(min.ToString()))); if (secondNullable is null && first >= secondDefault) { description.Append(' ').Append(Messages.Default); } - description.AppendLine().Append("- ").Append(string.Format( + description.AppendLine().AppendBulletPoint(string.Format( Messages.RandomMax, Markdown.InlineCode(max.ToString()))); if (secondNullable is null && first < secondDefault) { @@ -389,7 +389,7 @@ public class ToolsCommandGroup : CommandGroup .WithColour(embedColor) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct); } private static readonly TimestampStyle[] AllStyles = @@ -435,7 +435,7 @@ public class ToolsCommandGroup : CommandGroup return await SendTimestampAsync(offset, executor, CancellationToken); } - private async Task SendTimestampAsync(TimeSpan? offset, IUser executor, CancellationToken ct) + private Task SendTimestampAsync(TimeSpan? offset, IUser executor, CancellationToken ct) { var timestamp = DateTimeOffset.UtcNow.Add(offset ?? TimeSpan.Zero).ToUnixTimeSeconds(); @@ -449,7 +449,7 @@ public class ToolsCommandGroup : CommandGroup foreach (var markdownTimestamp in AllStyles.Select(style => Markdown.Timestamp(timestamp, style))) { - description.Append("- ").Append(Markdown.InlineCode(markdownTimestamp)) + description.AppendBulletPoint(Markdown.InlineCode(markdownTimestamp)) .Append(" → ").AppendLine(markdownTimestamp); } @@ -459,6 +459,6 @@ public class ToolsCommandGroup : CommandGroup .WithColour(ColorsList.Blue) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct); } } diff --git a/src/Data/MemberData.cs b/src/Data/MemberData.cs index b63f8ad..0b0cfb2 100644 --- a/src/Data/MemberData.cs +++ b/src/Data/MemberData.cs @@ -18,6 +18,6 @@ public sealed class MemberData public ulong Id { get; } public DateTimeOffset? BannedUntil { get; set; } public DateTimeOffset? MutedUntil { get; set; } - public List Roles { get; set; } = new(); - public List Reminders { get; } = new(); + public List Roles { get; set; } = []; + public List Reminders { get; } = []; } diff --git a/src/Extensions/CollectionExtensions.cs b/src/Extensions/CollectionExtensions.cs index 5322d09..9c873f2 100644 --- a/src/Extensions/CollectionExtensions.cs +++ b/src/Extensions/CollectionExtensions.cs @@ -8,7 +8,7 @@ public static class CollectionExtensions this IEnumerable source, Func selector) { var list = source.ToList(); - return list.Any() ? list.Max(selector) : default; + return list.Count > 0 ? list.Max(selector) : default; } public static void AddIfFailed(this List list, Result result) diff --git a/src/Extensions/MarkdownExtensions.cs b/src/Extensions/MarkdownExtensions.cs new file mode 100644 index 0000000..7b7f780 --- /dev/null +++ b/src/Extensions/MarkdownExtensions.cs @@ -0,0 +1,16 @@ +namespace Octobot.Extensions; + +public static class MarkdownExtensions +{ + /// + /// Formats a string to use Markdown Bullet formatting. + /// + /// The input text to format. + /// + /// A markdown-formatted bullet string. + /// + public static string BulletPoint(string text) + { + return $"- {text}"; + } +} diff --git a/src/Extensions/StringBuilderExtensions.cs b/src/Extensions/StringBuilderExtensions.cs new file mode 100644 index 0000000..ddd24a3 --- /dev/null +++ b/src/Extensions/StringBuilderExtensions.cs @@ -0,0 +1,62 @@ +using System.Text; + +namespace Octobot.Extensions; + +public static class StringBuilderExtensions +{ + /// + /// Appends the input string with Markdown Bullet formatting to the specified object. + /// + /// The object. + /// The string to append with bullet point. + /// + /// The builder with the appended string with Markdown Bullet formatting. + /// + public static StringBuilder AppendBulletPoint(this StringBuilder builder, string? value) + { + return builder.Append("- ").Append(value); + } + + /// + /// Appends the input string with Markdown Sub-Bullet formatting to the specified object. + /// + /// The object. + /// The string to append with sub-bullet point. + /// + /// The builder with the appended string with Markdown Sub-Bullet formatting. + /// + public static StringBuilder AppendSubBulletPoint(this StringBuilder builder, string? value) + { + return builder.Append(" - ").Append(value); + } + + /// + /// Appends the input string with Markdown Bullet formatting followed by + /// the default line terminator to the end of specified object. + /// + /// The object. + /// The string to append with bullet point. + /// + /// The builder with the appended string with Markdown Bullet formatting + /// and default line terminator at the end. + /// + public static StringBuilder AppendBulletPointLine(this StringBuilder builder, string? value) + { + return builder.Append("- ").AppendLine(value); + } + + /// + /// Appends the input string with Markdown Sub-Bullet formatting followed by + /// the default line terminator to the end of specified object. + /// + /// The object. + /// The string to append with sub-bullet point. + /// + /// The builder with the appended string with Markdown Sub-Bullet formatting + /// and default line terminator at the end. + /// + public static StringBuilder AppendSubBulletPointLine(this StringBuilder builder, string? value) + { + return builder.Append(" - ").AppendLine(value); + } +} diff --git a/src/Extensions/StringExtensions.cs b/src/Extensions/StringExtensions.cs index 13cd88a..cb8d606 100644 --- a/src/Extensions/StringExtensions.cs +++ b/src/Extensions/StringExtensions.cs @@ -45,7 +45,7 @@ public static class StringExtensions { s = s.SanitizeForBlockCode(); return - $"```{language}\n{s.SanitizeForBlockCode()}{(s.EndsWith("`", StringComparison.Ordinal) || string.IsNullOrWhiteSpace(s) ? " " : "")}```"; + $"```{language}\n{s.SanitizeForBlockCode()}{(s.EndsWith('`') || string.IsNullOrWhiteSpace(s) ? " " : "")}```"; } public static string Localized(this string key) diff --git a/src/Messages.Designer.cs b/src/Messages.Designer.cs index e2184d7..33ba7b3 100644 --- a/src/Messages.Designer.cs +++ b/src/Messages.Designer.cs @@ -534,9 +534,9 @@ namespace Octobot { } } - internal static string EventDetailsButton { + internal static string OpenEventInfoButton { get { - return ResourceManager.GetString("EventDetailsButton", resourceCulture); + return ResourceManager.GetString("OpenEventInfoButton", resourceCulture); } } @@ -1012,7 +1012,7 @@ namespace Octobot { return ResourceManager.GetString("DataLoadFailedDescription", resourceCulture); } } - + internal static string CommandExecutionFailed { get @@ -1020,7 +1020,7 @@ namespace Octobot { return ResourceManager.GetString("CommandExecutionFailed", resourceCulture); } } - + internal static string ContactDevelopers { get diff --git a/src/Services/GuildDataService.cs b/src/Services/GuildDataService.cs index d76fffc..3cc8cea 100644 --- a/src/Services/GuildDataService.cs +++ b/src/Services/GuildDataService.cs @@ -39,7 +39,7 @@ public sealed class GuildDataService : IHostedService SaveAsync(CancellationToken.None).GetAwaiter().GetResult(); } - public async Task SaveAsync(CancellationToken ct) + public Task SaveAsync(CancellationToken ct) { var tasks = new List(); var datas = _datas.Values.ToArray(); @@ -53,7 +53,7 @@ public sealed class GuildDataService : IHostedService SerializeObjectSafelyAsync(memberData, $"{data.MemberDataPath}/{memberData.Id}.json", ct))); } - await Task.WhenAll(tasks); + return Task.WhenAll(tasks); } private static async Task SerializeObjectSafelyAsync(T obj, string path, CancellationToken ct) diff --git a/src/Services/Update/ScheduledEventUpdateService.cs b/src/Services/Update/ScheduledEventUpdateService.cs index 8872ddc..9ec9fcf 100644 --- a/src/Services/Update/ScheduledEventUpdateService.cs +++ b/src/Services/Update/ScheduledEventUpdateService.cs @@ -126,7 +126,7 @@ public sealed class ScheduledEventUpdateService : BackgroundService { var filtered = from.Where(schEvent => schEvent.ID == id); var filteredArray = filtered.ToArray(); - return filteredArray.Any() + return filteredArray.Length > 0 ? Result.FromSuccess(filteredArray.Single()) : new NotFoundError(); } @@ -226,7 +226,7 @@ public sealed class ScheduledEventUpdateService : BackgroundService var button = new ButtonComponent( ButtonComponentStyle.Link, - Messages.EventDetailsButton, + Messages.OpenEventInfoButton, new PartialEmoji(Name: "📋"), URL: $"https://discord.com/events/{scheduledEvent.GuildID}/{scheduledEvent.ID}" ); diff --git a/src/Services/Update/SongUpdateService.cs b/src/Services/Update/SongUpdateService.cs index f1ef296..391c416 100644 --- a/src/Services/Update/SongUpdateService.cs +++ b/src/Services/Update/SongUpdateService.cs @@ -10,26 +10,29 @@ public sealed class SongUpdateService : BackgroundService { private static readonly (string Author, string Name, TimeSpan Duration)[] SongList = { - ("Yoko & the Gold Bazookas", "Rockagilly Blues", new TimeSpan(0, 3, 37)), - ("Splatoon 3", "Seep and Destroy", new TimeSpan(0, 2, 42)), - ("Deep Cut", "Big Betrayal", new TimeSpan(0, 1, 42)), - ("Squid Sisters", "Tomorrow's Nostalgia Today", new TimeSpan(0, 2, 8)), - ("Deep Cut", "Anarchy Rainbow", new TimeSpan(0, 1, 51)), - ("Squid Sisters feat. Ian BGM", "Liquid Sunshine", new TimeSpan(0, 1, 32)), - ("Damp Socks feat. Off the Hook", "Candy-Coated Rocks", new TimeSpan(0, 1, 11)), - ("H2Whoa", "Aquasonic", new TimeSpan(0, 1, 1)), - ("Yoko & the Gold Bazookas", "Ska-BLAM", new TimeSpan(0, 4, 4)), - ("Off the Hook", "Muck Warfare", new TimeSpan(0, 3, 39)), - ("Off the Hook", "Acid Hues", new TimeSpan(0, 3, 39)), - ("Off the Hook", "Shark Bytes", new TimeSpan(0, 3, 48)), - ("DJ Octavio feat. Squid Sisters & Deep Cut", "Calamari Inkantation 3MIX", new TimeSpan(0, 7, 9)), - ("Squid Sisters", "Ink Me Up", new TimeSpan(0, 2, 13)) + ("Yoko & the Gold Bazookas", "Rockagilly Blues", new TimeSpan(0, 2, 52)), + ("Deep Cut", "Big Betrayal", new TimeSpan(0, 5, 55)), + ("Squid Sisters", "Tomorrow's Nostalgia Today", new TimeSpan(0, 3, 7)), + ("Deep Cut", "Anarchy Rainbow", new TimeSpan(0, 3, 20)), + ("Squid Sisters feat. Ian BGM", "Liquid Sunshine", new TimeSpan(0, 2, 37)), + ("Damp Socks feat. Off the Hook", "Candy-Coated Rocks", new TimeSpan(0, 2, 58)), + ("H2Whoa", "Aquasonic", new TimeSpan(0, 2, 51)), + ("Yoko & the Gold Bazookas", "Ska-BLAM", new TimeSpan(0, 2, 57)), + ("Off the Hook", "Muck Warfare", new TimeSpan(0, 3, 20)), + ("Off the Hook", "Acid Hues", new TimeSpan(0, 3, 15)), + ("Off the Hook", "Shark Bytes", new TimeSpan(0, 3, 34)), + ("Squid Sisters", "Calamari Inkantation", new TimeSpan(0, 2, 14)), + ("Squid Sisters", "Ink Me Up", new TimeSpan(0, 2, 13)), + ("Chirpy Chips", "No Quarters", new TimeSpan(0, 2, 36)), + ("Chirpy Chips", "Shellfie", new TimeSpan(0, 2, 1)), + ("Dedf1sh", "#11 above", new TimeSpan(0, 2, 10)), + ("Callie", "Bomb Rush Blush", new TimeSpan(0, 2, 18)), + ("Turquoise October", "Octoling Rendezvous", new TimeSpan(0, 1, 57)), + ("Damp Socks feat. Off the Hook", "Tentacle to the Metal", new TimeSpan(0, 2, 51)), + ("Off the Hook", "Fly Octo Fly ~ Ebb & Flow (Octo)", new TimeSpan(0, 3, 5)) }; - private readonly List _activityList = new(1) - { - new Activity("with Remora.Discord", ActivityType.Game) - }; + private readonly List _activityList = [new Activity("with Remora.Discord", ActivityType.Game)]; private readonly DiscordGatewayClient _client; private readonly GuildDataService _guildData;