BirthdayBot/ApplicationCommands/TzAutocompleteHandler.cs

34 lines
1.8 KiB
C#
Raw Normal View History

using BirthdayBot.Data;
using Discord.Interactions;
using Microsoft.EntityFrameworkCore;
namespace BirthdayBot.ApplicationCommands;
public class TzAutocompleteHandler : AutocompleteHandler {
public override Task<AutocompletionResult> 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));
}
}