From 0df4864888bf08b478c88078062119501414dfee Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Tue, 1 Jul 2025 23:51:26 +0800 Subject: [PATCH] :sparkles: Auto completion handler for account and stickers --- .../Connection/AutoCompletionController.cs | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 DysonNetwork.Sphere/Connection/AutoCompletionController.cs diff --git a/DysonNetwork.Sphere/Connection/AutoCompletionController.cs b/DysonNetwork.Sphere/Connection/AutoCompletionController.cs new file mode 100644 index 0000000..702da71 --- /dev/null +++ b/DysonNetwork.Sphere/Connection/AutoCompletionController.cs @@ -0,0 +1,89 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace DysonNetwork.Sphere.Connection; + +[ApiController] +[Route("completion")] +public class AutoCompletionController(AppDatabase db) + : ControllerBase +{ + [HttpPost] + public async Task> GetCompletions([FromBody] AutoCompletionRequest request) + { + if (string.IsNullOrWhiteSpace(request?.Content)) + { + return BadRequest("Content is required"); + } + + var result = new AutoCompletionResponse(); + var lastWord = request.Content.Trim().Split(' ').LastOrDefault() ?? string.Empty; + + if (lastWord.StartsWith("@")) + { + var searchTerm = lastWord[1..]; // Remove the @ + result.Items = await GetAccountCompletions(searchTerm); + result.Type = "account"; + } + else if (lastWord.StartsWith(":")) + { + var searchTerm = lastWord[1..]; // Remove the : + result.Items = await GetStickerCompletions(searchTerm); + result.Type = "sticker"; + } + + return Ok(result); + } + + private async Task> GetAccountCompletions(string searchTerm) + { + return await db.Accounts + .Where(a => EF.Functions.ILike(a.Name, $"%{searchTerm}%")) + .OrderBy(a => a.Name) + .Take(10) + .Select(a => new CompletionItem + { + Id = a.Id.ToString(), + DisplayName = a.Name, + SecondaryText = a.Nick, + Type = "account" + }) + .ToListAsync(); + } + + private async Task> GetStickerCompletions(string searchTerm) + { + return await db.Stickers + .Include(s => s.Pack) + .Where(s => EF.Functions.ILike(s.Pack.Prefix + s.Slug, $"%{searchTerm}%")) + .OrderBy(s => s.Slug) + .Take(10) + .Select(s => new CompletionItem + { + Id = s.Id.ToString(), + DisplayName = s.Slug, + Type = "sticker" + }) + .ToListAsync(); + } +} + +public class AutoCompletionRequest +{ + [Required] public string Content { get; set; } = string.Empty; +} + +public class AutoCompletionResponse +{ + public string Type { get; set; } = string.Empty; + public List Items { get; set; } = new(); +} + +public class CompletionItem +{ + public string Id { get; set; } = string.Empty; + public string DisplayName { get; set; } = string.Empty; + public string? SecondaryText { get; set; } + public string Type { get; set; } = string.Empty; +} \ No newline at end of file