From 3eed00cd52dcacece5e54f9601ba889e39eb5522 Mon Sep 17 00:00:00 2001 From: Noi Date: Sat, 6 Jul 2024 19:42:36 -0700 Subject: [PATCH] Add autocomplete to time zone parameter --- ApplicationCommands/BirthdayModule.cs | 4 +- ApplicationCommands/BirthdayOverrideModule.cs | 2 +- ApplicationCommands/TzAutocompleteHandler.cs | 117 ++++++++++++++++++ BirthdayBot.csproj | 2 +- 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 ApplicationCommands/TzAutocompleteHandler.cs 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/TzAutocompleteHandler.cs b/ApplicationCommands/TzAutocompleteHandler.cs new file mode 100644 index 0000000..dd74a26 --- /dev/null +++ b/ApplicationCommands/TzAutocompleteHandler.cs @@ -0,0 +1,117 @@ +using System.Collections.ObjectModel; +using CommandLine; +using Discord.Interactions; +using System.Linq; + +namespace BirthdayBot.ApplicationCommands; + +public class TzAutocompleteHandler : AutocompleteHandler { + public override Task GenerateSuggestionsAsync(IInteractionContext cx, + IAutocompleteInteraction ia, IParameterInfo pm, + IServiceProvider sv) { + var userInput = ((SocketAutocompleteInteraction)ia).Data.Current.Value.ToString()!; + var input = userInput.Split('/', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + + if (input.Length < 2) { + // Suggest region if not given + } else { + // Suggest within region + + } + + IEnumerable results = new[] + { + new AutocompleteResult("foo", "foo_value"), + new AutocompleteResult("bar", "bar_value"), + new AutocompleteResult("baz", "baz_value"), + }.Where(x => x.Name.StartsWith(userInput, StringComparison.InvariantCultureIgnoreCase)); // only send suggestions that starts with user's input; use case insensitive matching + + + // max - 25 suggestions at a time + return Task.FromResult(AutocompletionResult.FromSuccess(results.Take(25))); + } + + private void RefreshTopZones() { + + } + + private static readonly ReadOnlyCollection SuggestedRegions; + private static readonly ReadOnlyDictionary> SuggestedZones; + + static TzAutocompleteHandler() { + // TODO After ensuring this list is fine, have this created automatically at bot startup. Query used: + // select time_zone as tz, count(*) + // from user_birthdays + // where starts_with(time_zone, 'America/') -- use with: Africa America Antarctica Asia Atlantic Australia Europe Pacific + // group by tz + // order by count desc + // limit 100; + // Should also find a way to include zones with counts of 0 for full completion + + var Africa = new List() { + "Cairo", "Johannesburg", "Casablanca", "Algiers", "Tunis", "Lagos", "Nairobi", "Dakar", "Abidjan", + "Khartoum", "Accra", "Maputo", "Tripoli", "Harare", "Windhoek", "Gaborone", "Lusaka", "Luanda", "Kigali", + "Ceuta", "Lubumbashi", "Addis_Ababa", "Malabo", "Blantyre", "Maseru", "Monrovia", "Banjul", "Niamey", + "Porto-Novo", "Bangui", "Asmera", "Dar_es_Salaam", "Juba" + }.AsReadOnly(); + var America = new List() { + "New_York", "Chicago", "Los_Angeles", "Toronto", "Denver", "Mexico_City", "Sao_Paulo", "Vancouver", "Phoenix", + "Santiago", "Buenos_Aires", "Detroit", "Edmonton", "Bogota", "Lima", "Argentina/Buenos_Aires", "Winnipeg", + "Montreal", "Halifax", "Regina", "Caracas", "Indianapolis", "Montevideo", "Guayaquil", "Anchorage", + "Costa_Rica", "Panama", "Puerto_Rico", "Boise", "Monterrey", "Guatemala", "Santo_Domingo", "St_Johns", + "Port_of_Spain", "Chihuahua", "Tijuana", "El_Salvador", "Moncton", "La_Paz", "Indiana/Indianapolis", + "Fortaleza", "Tegucigalpa", "Hermosillo", "Bahia", "Louisville", "Jamaica", "Asuncion", "Belem", + "Santa_Isabel", "Argentina/Cordoba", "Cancun", "Kentucky/Louisville", "Mazatlan", "Indiana/Knox", "Manaus", + "Recife", "Merida", "Barbados", "Managua", "Bahia_Banderas", "Guyana", "Matamoros", "Cuiaba", "Belize", + "Paramaribo", "Cordoba", "Havana", "North_Dakota/Center", "Nome", "Adak", "Shiprock", "Fort_Wayne", + "Godthab", "Swift_Current", "Anguilla", "Argentina/Salta", "Whitehorse", "Campo_Grande", "Yellowknife", + "Araguaina", "Guadeloupe", "Menominee", "Nassau", "Nuuk", "Ojinaga", "Virgin", "Goose_Bay", + "Argentina/Tucuman", "Rainy_River", "North_Dakota/New_Salem", "Scoresbysund", "Martinique", "Atikokan", + "Creston", "Glace_Bay", "Tortola", "Rankin_Inlet", "Knox_IN", "Iqaluit", "North_Dakota/Beulah" + }.AsReadOnly(); + var Antarctica = new List() { + "McMurdo", "Troll", "DumontDUrville", "Macquarie", "South_Pole" + }.AsReadOnly(); + var Asia = new List() { + "Manila", "Kolkata", "Calcutta", "Jakarta", "Kuala_Lumpur", "Singapore", "Bangkok", "Riyadh", "Dubai", + "Saigon", "Tokyo", "Hong_Kong", "Seoul", "Dhaka", "Ho_Chi_Minh", "Karachi", "Shanghai", "Taipei", "Makassar", + "Jerusalem", "Tehran", "Yekaterinburg", "Qatar", "Baghdad", "Colombo", "Beirut", "Bahrain", "Kuching", + "Rangoon", "Amman", "Kuwait", "Muscat", "Almaty", "Brunei", "Tbilisi", "Phnom_Penh", "Kathmandu", + "Vladivostok", "Krasnoyarsk", "Nicosia", "Katmandu", "Yangon", "Baku", "Ulaanbaatar", "Pontianak", "Yakutsk", + "Novosibirsk", "Yerevan", "Irkutsk", "Macau", "Tashkent", "Damascus", "Omsk", "Bishkek", "Macao", "Dili", + "Jayapura", "Pyongyang", "Chongqing", "Tomsk", "Kamchatka", "Vientiane", "Kabul", "Novokuznetsk", "Istanbul", + "Sakhalin", "Choibalsan", "Hovd", "Khandyga", "Dacca", "Ashgabat", "Tel_Aviv", "Chita", "Oral", "Magadan", + "Hebron", "Gaza", "Srednekolymsk", "Anadyr", "Urumqi", "Barnaul", "Aqtobe" + }.AsReadOnly(); + var Atlantic = new List() { + "Canary", "Reykjavik", "Azores", "South_Georgia", "Faroe", "Stanley" + }.AsReadOnly(); + var Australia = new List() { + "Sydney", "Melbourne", "Brisbane", "Perth", "Adelaide", "Victoria", "Queensland", "Hobart", "NSW", "Darwin", + "Canberra", "Tasmania", "West", "South", "Currie", "ACT", "North", "Lindeman", "Broken_Hill" + }.AsReadOnly(); + var Europe = new List() { + "London", "Berlin", "Paris", "Amsterdam", "Madrid", "Stockholm", "Warsaw", "Rome", "Moscow", "Brussels", + "Prague", "Helsinki", "Oslo", "Bucharest", "Lisbon", "Copenhagen", "Dublin", "Istanbul", "Athens", "Vienna", + "Budapest", "Zurich", "Vilnius", "Kiev", "Sofia", "Belgrade", "Tallinn", "Zagreb", "Bratislava", "Riga", + "Ljubljana", "Sarajevo", "Kyiv", "Luxembourg", "Minsk", "Skopje", "Chisinau", "Tirane", "Samara", "Belfast", + "Malta", "Kaliningrad", "Podgorica", "Monaco", "Gibraltar", "Volgograd", "Busingen", "Jersey", "Zaporozhye", + "Saratov", "Andorra", "Astrakhan", "Isle_of_Man", "Guernsey", "Vaduz", "Vatican", "Nicosia", "Tiraspol" + }.AsReadOnly(); + var Pacific = new List() { + "Auckland", "Honolulu", "Guam", "Fiji", "Port_Moresby", "Rarotonga", "Noumea", "Kiritimati", "Apia", + "Tahiti", "Majuro", "Midway", "Pago_Pago", "Palau", "Saipan" + }.AsReadOnly(); + + SuggestedZones = new Dictionary> { + { "Africa", Africa }, + { "America", America }, + { "Antarctica", Antarctica }, + { "Asia", Asia }, + { "Australia", Australia }, + { "Europe", Europe }, + { "Pacific", Pacific } + }.AsReadOnly(); + SuggestedRegions = SuggestedZones.Select(i => i.Key).ToList().AsReadOnly(); + } +} \ 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