Iceshrimp.NET/Iceshrimp.Frontend/Components/EmojiManagementEntry.razor

237 lines
8.5 KiB
Text

@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Core.Miscellaneous
@using Iceshrimp.Frontend.Core.Services
@inject ApiService Api;
@inject GlobalComponentSvc Global;
@inject IStringLocalizer<Localization> Loc;
<div @ref="EmojiButton" class="emoji-entry" @onclick="SelectEmoji" @onclick:stopPropagation="true">
<InlineEmoji Name="@Emoji.Name" Url="@Emoji.PublicUrl" Hover="@true" Size="3rem"/>
<div class="emoji-details">
<span class="emoji-name">@Emoji.Name</span>
<span class="emoji-meta">
@if (Remote)
{
@Emoji.Category
}
else
{
@foreach (var tag in Emoji.Tags)
{
<span>@tag</span>
}
}
</span>
<span class="labels">
@if (Emoji.Sensitive)
{
<Icon Name="Icons.EyeSlash" title="@Loc["Sensitive"]"/>
}
@if (!string.IsNullOrWhiteSpace(Emoji.License))
{
<Icon Name="Icons.Article" title="@Emoji.License"/>
}
</span>
</div>
<Menu @ref="EmojiMenu">
@if (Remote)
{
<MenuElement Icon="Icons.Copy" OnSelect="Clone">
<Text>@Loc["Clone"]</Text>
</MenuElement>
}
else
{
<MenuElement Icon="Icons.CursorText" OnSelect="Rename">
<Text>@Loc["Rename"]</Text>
</MenuElement>
}
@if (Emoji.Sensitive)
{
<MenuElement Icon="Icons.Eye" OnSelect="MarkNotSensitive">
<Text>@Loc["Mark as not sensitive"]</Text>
</MenuElement>
}
else
{
<MenuElement Icon="Icons.EyeSlash" OnSelect="MarkAsSensitive">
<Text>@Loc["Mark as sensitive"]</Text>
</MenuElement>
}
@if (!Remote)
{
<MenuElement Icon="Icons.TextAa" OnSelect="SetTags">
<Text>@Loc["Set tags"]</Text>
</MenuElement>
<MenuElement Icon="Icons.Folder" OnSelect="SetCategory">
<Text>@Loc["Set category"]</Text>
</MenuElement>
<MenuElement Icon="Icons.Article" OnSelect="SetLicense">
<Text>@Loc["Set license"]</Text>
</MenuElement>
<hr class="rule"/>
<MenuElement Icon="Icons.Trash" OnSelect="Delete" Danger>
<Text>@Loc["Delete"]</Text>
</MenuElement>
}
<ClosingBackdrop OnClose="EmojiMenu.Close"></ClosingBackdrop>
</Menu>
</div>
@code {
[Parameter, EditorRequired] public required EmojiResponse Emoji { get; set; }
[Parameter] public bool Remote { get; set; }
[Parameter] public EventCallback GetEmojis { get; set; }
private ElementReference EmojiButton { get; set; }
private Menu EmojiMenu { get; set; } = null!;
private void SelectEmoji() => EmojiMenu.Toggle(EmojiButton);
private async Task Clone() =>
await Global.ConfirmDialog?.Confirm(new EventCallback<bool>(this, CloneCallback), @Loc["Clone {0} from {1}?", Emoji.Name, Emoji.Category ?? ""], Icons.Copy, @Loc["Clone"])!;
private async Task CloneCallback(bool confirm)
{
if (!confirm || !Remote || Emoji.Category == null) return;
try
{
// Remote emojis endpoint sets EmojiResponse.Category to the emoji's host
var res = await Api.Emoji.CloneEmojiAsync(Emoji.Name, Emoji.Category);
if (res != null) await Global.NoticeDialog?.Display(Loc["Cloned {0} from {1}", Emoji.Name, Emoji.Category])!;
}
catch (ApiException e)
{
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!;
}
}
private async Task Rename() =>
await Global.PromptDialog?.Prompt(new EventCallback<string?>(this, RenameCallback), Loc["Rename emoji"], "", Emoji.Name, buttonText: Loc["Rename"])!;
private async Task RenameCallback(string? name)
{
if (string.IsNullOrWhiteSpace(name)) return;
try
{
var res = await Api.Emoji.UpdateEmojiAsync(Emoji.Id, new UpdateEmojiRequest { Name = name });
if (res != null)
{
Emoji.Name = res.Name;
StateHasChanged();
}
}
catch (ApiException e)
{
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!;
}
}
private async Task MarkSensitive(bool sensitive)
{
try
{
var res = await Api.Emoji.UpdateEmojiAsync(Emoji.Id, new UpdateEmojiRequest { Sensitive = sensitive });
if (res != null)
{
Emoji.Sensitive = res.Sensitive;
StateHasChanged();
}
}
catch (ApiException e)
{
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!;
}
}
private async Task MarkNotSensitive() => await MarkSensitive(false);
private async Task MarkAsSensitive() => await MarkSensitive(true);
private async Task SetTags() =>
await Global.PromptDialog?.Prompt(new EventCallback<string?>(this, SetTagsCallback), Loc["Set tags (separated by new line)"], "one\ntwo\nthree", string.Join("\n", Emoji.Tags), true, true)!;
private async Task SetTagsCallback(string? tags)
{
if (tags == null) return;
try
{
var res = await Api.Emoji.UpdateEmojiAsync(Emoji.Id, new UpdateEmojiRequest { Tags = string.IsNullOrWhiteSpace(tags) ? [] : tags.Replace(" ", "").Split("\n").ToList() });
if (res != null)
{
Emoji.Tags = res.Tags;
StateHasChanged();
}
}
catch (ApiException e)
{
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!;
}
}
private async Task SetCategory() =>
await Global.PromptDialog?.Prompt(new EventCallback<string?>(this, SetCategoryCallback), Loc["Set category"], "", Emoji.Category, true)!;
private async Task SetCategoryCallback(string? category)
{
if (category == null) return;
try
{
var res = await Api.Emoji.UpdateEmojiAsync(Emoji.Id, new UpdateEmojiRequest { Category = category });
if (res != null)
{
Emoji.Category = res.Category;
await GetEmojis.InvokeAsync();
}
}
catch (ApiException e)
{
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!;
}
}
private async Task SetLicense() =>
await Global.PromptDialog?.Prompt(new EventCallback<string?>(this, SetLicenseCallback), Loc["Set license"], "", Emoji.License, true, true)!;
private async Task SetLicenseCallback(string? license)
{
if (license == null) return;
try
{
var res = await Api.Emoji.UpdateEmojiAsync(Emoji.Id, new UpdateEmojiRequest { License = license });
if (res != null)
{
Emoji.License = res.License;
StateHasChanged();
}
}
catch (ApiException e)
{
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!;
}
}
private async Task Delete() =>
await Global.ConfirmDialog?.Confirm(new EventCallback<bool>(this, DeleteCallback), Loc["Delete {0}?", Emoji.Name], Icons.Trash, Loc["Delete"])!;
private async Task DeleteCallback(bool delete)
{
if (!delete) return;
try
{
var res = await Api.Emoji.DeleteEmojiAsync(Emoji.Id);
if (res) await GetEmojis.InvokeAsync();
}
catch (ApiException e)
{
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!;
}
}
}