From 3eed00cd52dcacece5e54f9601ba889e39eb5522 Mon Sep 17 00:00:00 2001 From: Noi Date: Sat, 6 Jul 2024 19:42:36 -0700 Subject: [PATCH 1/5] 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 From 669579f477901bf1190d20621e73c939198d79e1 Mon Sep 17 00:00:00 2001 From: Noi Date: Sat, 6 Jul 2024 20:15:29 -0700 Subject: [PATCH 2/5] Send full, not partial completions Users accepting a partial suggestion get kicked out of the input field. Not very good for usability. Instead, perhaps a full list will do. More improvements needed. --- ApplicationCommands/TzAutocompleteHandler.cs | 113 +++---------------- 1 file changed, 16 insertions(+), 97 deletions(-) diff --git a/ApplicationCommands/TzAutocompleteHandler.cs b/ApplicationCommands/TzAutocompleteHandler.cs index dd74a26..5d736ec 100644 --- a/ApplicationCommands/TzAutocompleteHandler.cs +++ b/ApplicationCommands/TzAutocompleteHandler.cs @@ -10,108 +10,27 @@ public class TzAutocompleteHandler : AutocompleteHandler { 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 + var results = Top25.Select(i => new AutocompleteResult(i, i)) + .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(); - } + private static readonly ReadOnlyCollection Top25 = new List() { + "America/New_York", "America/Chicago", "America/Los_Angeles", "Europe/London", "Asia/Manila", "Europe/Berlin", + "Europe/Paris", "Europe/Amsterdam", "Asia/Kolkata", "Australia/Sydney", "Asia/Calcutta", "Asia/Jakarta", + "America/Toronto", "Asia/Kuala_Lumpur", "America/Denver", "Europe/Madrid", "Australia/Melbourne", + "Asia/Singapore", "America/Mexico_City", "Australia/Brisbane", "America/Sao_Paulo", "Pacific/Auckland", + "Europe/Stockholm", "America/Vancouver", "Europe/Warsaw" + }.AsReadOnly(); + // select time_zone as tz, count(*) + // from user_birthdays + // where time_zone like '%/%' + // group by tz + // order by count desc + // limit ???; + // TODO Should also find a way to include zones with counts of 0 for full completion } \ No newline at end of file From 1d1f8e2e43d46e2202fc1875c3b90338f3288027 Mon Sep 17 00:00:00 2001 From: Noi Date: Sat, 6 Jul 2024 21:58:41 -0700 Subject: [PATCH 3/5] Use database directly for tz popularity order --- ApplicationCommands/TzAutocompleteHandler.cs | 47 +++++++++----------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/ApplicationCommands/TzAutocompleteHandler.cs b/ApplicationCommands/TzAutocompleteHandler.cs index 5d736ec..089d77d 100644 --- a/ApplicationCommands/TzAutocompleteHandler.cs +++ b/ApplicationCommands/TzAutocompleteHandler.cs @@ -1,7 +1,7 @@ -using System.Collections.ObjectModel; -using CommandLine; + +using BirthdayBot.Data; using Discord.Interactions; -using System.Linq; +using Microsoft.EntityFrameworkCore; namespace BirthdayBot.ApplicationCommands; @@ -9,28 +9,25 @@ 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 = ((SocketAutocompleteInteraction)ia).Data.Current.Value.ToString()!; + var inparts = input.Split('/', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - var results = Top25.Select(i => new AutocompleteResult(i, i)) - .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))); + 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 Should also find a way to include zones with counts of 0 for full completion (with a join, maybe) + 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)); } - - private static readonly ReadOnlyCollection Top25 = new List() { - "America/New_York", "America/Chicago", "America/Los_Angeles", "Europe/London", "Asia/Manila", "Europe/Berlin", - "Europe/Paris", "Europe/Amsterdam", "Asia/Kolkata", "Australia/Sydney", "Asia/Calcutta", "Asia/Jakarta", - "America/Toronto", "Asia/Kuala_Lumpur", "America/Denver", "Europe/Madrid", "Australia/Melbourne", - "Asia/Singapore", "America/Mexico_City", "Australia/Brisbane", "America/Sao_Paulo", "Pacific/Auckland", - "Europe/Stockholm", "America/Vancouver", "Europe/Warsaw" - }.AsReadOnly(); - // select time_zone as tz, count(*) - // from user_birthdays - // where time_zone like '%/%' - // group by tz - // order by count desc - // limit ???; - // TODO Should also find a way to include zones with counts of 0 for full completion } \ No newline at end of file From 30ac9886d591197d88ea8b6087728901da2e9287 Mon Sep 17 00:00:00 2001 From: Noi Date: Sat, 6 Jul 2024 22:02:39 -0700 Subject: [PATCH 4/5] Use autocomplete in server tz config --- ApplicationCommands/ConfigModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) { From ee9e0b0444c451abf6deeac556b2c2e9bcb8e2ae Mon Sep 17 00:00:00 2001 From: Noi Date: Sun, 7 Jul 2024 23:41:06 -0700 Subject: [PATCH 5/5] Add to-do list comments This comes after several hours of attempting to implement what the first line suggests. A join in this situation is quite difficult and the importance of this feature does not outweigh the potentially high resource use of any other possible solutions for making it happen. For now, at least. --- ApplicationCommands/TzAutocompleteHandler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ApplicationCommands/TzAutocompleteHandler.cs b/ApplicationCommands/TzAutocompleteHandler.cs index 089d77d..dd016b4 100644 --- a/ApplicationCommands/TzAutocompleteHandler.cs +++ b/ApplicationCommands/TzAutocompleteHandler.cs @@ -21,7 +21,8 @@ public class TzAutocompleteHandler : AutocompleteHandler { query = query.Where(u => EF.Functions.ILike(u.TimeZone!, $"%{input}%/%") || EF.Functions.ILike(u.TimeZone!, $"%/%{input}%")); } - // TODO Should also find a way to include zones with counts of 0 for full completion (with a join, maybe) + // 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)