85 lines
No EOL
3.2 KiB
Text
85 lines
No EOL
3.2 KiB
Text
@using AngleSharp.Text
|
|
@using Iceshrimp.Frontend.Core.Services
|
|
@using Iceshrimp.Frontend.Localization
|
|
@using Iceshrimp.Shared.Schemas.Web
|
|
@using Microsoft.Extensions.Localization
|
|
@inject EmojiService EmojiService
|
|
@inject GlobalComponentSvc GlobalComponentSvc
|
|
@inject IJSRuntime Js
|
|
@inject IStringLocalizer<Localization> Loc;
|
|
|
|
<dialog class="dialog" @ref="EmojiPickerRef">
|
|
<div class="emoji-picker" style="--top: @(_top)px; --left: @(_left)px">
|
|
<input @bind="EmojiFilter" @bind:event="oninput" @bind:after="FilterEmojis" class="search" type="text" placeholder="Search" aria-label="search"/>
|
|
@foreach (var category in Categories)
|
|
{
|
|
<details open>
|
|
<summary aria-label="category">@category.Key</summary>
|
|
<div class="emoji-list">
|
|
@foreach (var emoji in category.Value)
|
|
{
|
|
<div @onclick="() => Select(emoji)" class="emoji" title=":@emoji.Name:">
|
|
<InlineEmoji Name="@emoji.Name" Url="@emoji.PublicUrl" Size="2rem"/>
|
|
</div>
|
|
}
|
|
</div>
|
|
</details>
|
|
}
|
|
</div>
|
|
<ClosingBackdrop OnClose="Close"></ClosingBackdrop>
|
|
</dialog>
|
|
|
|
|
|
@code {
|
|
private EventCallback<EmojiResponse> OnEmojiSelect { get; set; }
|
|
private List<EmojiResponse> EmojiList { get; set; } = [];
|
|
private ElementReference EmojiPickerRef { get; set; }
|
|
private float _top;
|
|
private float _left;
|
|
private IJSInProcessObjectReference _module = null!;
|
|
|
|
private string EmojiFilter { get; set; } = "";
|
|
private Dictionary<string, List<EmojiResponse>> Categories { get; set; } = [];
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
GlobalComponentSvc.EmojiPicker = this;
|
|
EmojiList = await EmojiService.GetEmojiAsync();
|
|
_module = (IJSInProcessObjectReference)await Js.InvokeAsync<IJSObjectReference>("import",
|
|
"./Components/EmojiPicker.razor.js");
|
|
FilterEmojis();
|
|
}
|
|
|
|
private async Task Select(EmojiResponse emoji)
|
|
{
|
|
await OnEmojiSelect.InvokeAsync(emoji);
|
|
Close();
|
|
}
|
|
|
|
private void Close()
|
|
{
|
|
_module.InvokeVoid("closeDialog", EmojiPickerRef);
|
|
}
|
|
|
|
public void Open(ElementReference root, EventCallback<EmojiResponse> func)
|
|
{
|
|
OnEmojiSelect = func;
|
|
var pos = _module.Invoke<List<float>>("getPosition", root);
|
|
_left = pos[0];
|
|
_top = pos[1];
|
|
StateHasChanged();
|
|
_module.InvokeVoid("openDialog", EmojiPickerRef);
|
|
}
|
|
|
|
private void FilterEmojis()
|
|
{
|
|
Categories = EmojiList
|
|
.Where(p => p.Name.Contains(EmojiFilter.StripLeadingTrailingSpaces()) || p.Tags.Count(a => a.Contains(EmojiFilter.StripLeadingTrailingSpaces())) != 0)
|
|
.OrderBy(p => p.Name)
|
|
.ThenBy(p => p.Id)
|
|
.GroupBy(p => p.Category)
|
|
.OrderBy(p => string.IsNullOrEmpty(p.Key))
|
|
.ThenBy(p => p.Key)
|
|
.ToDictionary(p => p.Key ?? Loc["Other"], p => p.ToList());
|
|
}
|
|
} |