diff --git a/ApplicationCommands/BirthdayModule.cs b/ApplicationCommands/BirthdayModule.cs index 2f5f670..df6503d 100644 --- a/ApplicationCommands/BirthdayModule.cs +++ b/ApplicationCommands/BirthdayModule.cs @@ -20,7 +20,7 @@ public class BirthdayModule : BotModuleBase { public class SubCmdsBirthdaySet : BotModuleBase { [SlashCommand("date", HelpCmdSetDate)] public async Task CmdSetBday([Summary(description: HelpOptDate)] string date, - [Summary(description: HelpOptZone)] string? zone = null) { + [Summary(description: HelpOptZone), Autocomplete] string? zone = null) { int inmonth, inday; try { (inmonth, inday) = ParseDate(date); @@ -59,7 +59,7 @@ public class BirthdayModule : BotModuleBase { } [SlashCommand("timezone", HelpCmdSetZone)] - public async Task CmdSetZone([Summary(description: HelpOptZone)] string zone) { + public async Task CmdSetZone([Summary(description: HelpOptZone), Autocomplete] string zone) { using var db = new BotDatabaseContext(); var user = ((SocketGuildUser)Context.User).GetUserEntryOrNew(db); diff --git a/ApplicationCommands/BirthdayOverrideModule.cs b/ApplicationCommands/BirthdayOverrideModule.cs index c261f94..d89c60b 100644 --- a/ApplicationCommands/BirthdayOverrideModule.cs +++ b/ApplicationCommands/BirthdayOverrideModule.cs @@ -44,7 +44,7 @@ public class BirthdayOverrideModule : BotModuleBase { [SlashCommand("set-timezone", "Set a user's time zone on their behalf.")] public async Task OvSetTimezone([Summary(description: HelpOptOvTarget)] SocketGuildUser target, - [Summary(description: HelpOptZone)] string zone) { + [Summary(description: HelpOptZone), Autocomplete] string zone) { using var db = new BotDatabaseContext(); var user = target.GetUserEntryOrNew(db); diff --git a/ApplicationCommands/ConfigModule.cs b/ApplicationCommands/ConfigModule.cs index 81c55a1..2c730b0 100644 --- a/ApplicationCommands/ConfigModule.cs +++ b/ApplicationCommands/ConfigModule.cs @@ -193,7 +193,7 @@ public class ConfigModule : BotModuleBase { } [SlashCommand("set-timezone", "Configure the time zone to use by default in the server." + HelpPofxBlankUnset)] - public async Task CmdSetTimezone([Summary(description: HelpOptZone)] string? zone = null) { + public async Task CmdSetTimezone([Summary(description: HelpOptZone), Autocomplete] string? zone = null) { const string Response = ":white_check_mark: The server's time zone has been "; if (zone == null) { diff --git a/ApplicationCommands/TzAutocompleteHandler.cs b/ApplicationCommands/TzAutocompleteHandler.cs new file mode 100644 index 0000000..dd016b4 --- /dev/null +++ b/ApplicationCommands/TzAutocompleteHandler.cs @@ -0,0 +1,34 @@ + +using BirthdayBot.Data; +using Discord.Interactions; +using Microsoft.EntityFrameworkCore; + +namespace BirthdayBot.ApplicationCommands; + +public class TzAutocompleteHandler : AutocompleteHandler { + public override Task GenerateSuggestionsAsync(IInteractionContext cx, + IAutocompleteInteraction ia, IParameterInfo pm, + IServiceProvider sv) { + var input = ((SocketAutocompleteInteraction)ia).Data.Current.Value.ToString()!; + var inparts = input.Split('/', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + + var db = new BotDatabaseContext(); + var query = db.UserEntries.AsNoTracking(); + if (inparts.Length == 2) { + query = query.Where(u => EF.Functions.ILike(u.TimeZone!, $"%{inparts[0]}%/%{inparts[1]}%")); + } else { + // No '/' in query - search for string within each side of zone name (tested to not give conflicting results) + query = query.Where(u => + EF.Functions.ILike(u.TimeZone!, $"%{input}%/%") || EF.Functions.ILike(u.TimeZone!, $"%/%{input}%")); + } + // TODO Could find a way to include all remaining zones at the bottom of results for full completion + // TODO Filter out undesirable zone names, aliases, etc from autocompletion + var result = query.GroupBy(u => u.TimeZone) + .Select(g => new { ZoneName = g.Key, Count = g.Count() }) + .OrderByDescending(x => x.Count) + .Take(25) + .Select(x => new AutocompleteResult(x.ZoneName, x.ZoneName)) + .ToList(); + return Task.FromResult(AutocompletionResult.FromSuccess(result)); + } +} \ No newline at end of file diff --git a/BirthdayBot.csproj b/BirthdayBot.csproj index 34b1e37..b5ecd18 100644 --- a/BirthdayBot.csproj +++ b/BirthdayBot.csproj @@ -24,7 +24,7 @@ - + all