diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index c08fa4d..e71a955 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -26,6 +26,6 @@ jobs: uses: muno92/resharper_inspectcode@1.11.0 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..41ac76b 100644 --- a/Octobot.csproj +++ b/Octobot.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 enable enable 2.0.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 47a9755..7c087e1 100644 --- a/src/Commands/RemindCommandGroup.cs +++ b/src/Commands/RemindCommandGroup.cs @@ -72,10 +72,10 @@ public class RemindCommandGroup : CommandGroup var data = await _guildData.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); - return await ListRemindersAsync(data.GetOrCreateMemberData(executorId), executor, bot, guildId, CancellationToken); + return await ListRemindersAsync(data.GetOrCreateMemberData(executorId), executor, bot, CancellationToken); } - private async Task ListRemindersAsync(MemberData data, IUser executor, IUser bot, Snowflake guildId, CancellationToken ct) + private async Task ListRemindersAsync(MemberData data, IUser executor, IUser bot, CancellationToken ct) { if (data.Reminders.Count == 0) { @@ -90,12 +90,9 @@ public class RemindCommandGroup : CommandGroup 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))) - .AppendLine(string.Format(Messages.DescriptionActionJumpToMessage, $"https://discord.com/channels/{guildId.Value}/{reminder.Channel}/{reminder.MessageId}") - ); + 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( @@ -149,30 +146,26 @@ public class RemindCommandGroup : CommandGroup var remindAt = DateTimeOffset.UtcNow.Add(@in); var memberData = data.GetOrCreateMemberData(executor.ID); - var builder = new StringBuilder().Append("- ").AppendLine(string.Format( - Messages.ReminderText, Markdown.InlineCode(text))) - .Append("- ").Append(string.Format(Messages.ReminderTime, Markdown.Timestamp(remindAt))); - - var embed = new EmbedBuilder().WithSmallTitle( - string.Format(Messages.ReminderCreated, executor.GetTag()), executor) - .WithDescription(builder.ToString()) - .WithColour(ColorsList.Green) - .WithFooter(string.Format(Messages.ReminderPosition, memberData.Reminders.Count + 1)) - .Build(); - var messageResult = await _feedback.SendContextualEmbedAsync(embed.Entity, ct: ct); - if (!messageResult.IsDefined(out var output)) { return (Result)messageResult; } - - var messageId = output.ID.Value; - memberData.Reminders.Add( new Reminder { At = remindAt, Channel = channelId.Value, - Text = text, - MessageId = messageId.ToString() + Text = text }); - return (Result)messageResult; + + var builder = new StringBuilder().AppendBulletPointLine(string.Format( + Messages.ReminderText, Markdown.InlineCode(text))) + .AppendBulletPoint(string.Format(Messages.ReminderTime, Markdown.Timestamp(remindAt))); + + var embed = new EmbedBuilder().WithSmallTitle( + string.Format(Messages.ReminderCreated, executor.GetTag()), executor) + .WithDescription(builder.ToString()) + .WithColour(ColorsList.Green) + .WithFooter(string.Format(Messages.ReminderPosition, memberData.Reminders.Count)) + .Build(); + + return await _feedback.SendContextualEmbedResultAsync(embed, ct); } /// @@ -221,8 +214,8 @@ public class RemindCommandGroup : CommandGroup 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); diff --git a/src/Commands/SettingsCommandGroup.cs b/src/Commands/SettingsCommandGroup.cs index 2c114c1..dd0e9e3 100644 --- a/src/Commands/SettingsCommandGroup.cs +++ b/src/Commands/SettingsCommandGroup.cs @@ -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) diff --git a/src/Commands/ToolsCommandGroup.cs b/src/Commands/ToolsCommandGroup.cs index c0b99f5..0cb237a 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))); } } @@ -282,13 +282,13 @@ public class ToolsCommandGroup : CommandGroup 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; } @@ -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) { @@ -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); } 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/Services/Update/ScheduledEventUpdateService.cs b/src/Services/Update/ScheduledEventUpdateService.cs index 8872ddc..af940c8 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(); }