Iceshrimp.NET/Iceshrimp.Frontend/Components/ComposeAttachment.razor

148 lines
No EOL
5.5 KiB
Text

@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Core.Miscellaneous
@inject ApiService Api;
@inject GlobalComponentSvc Global;
@inject IJSRuntime Js;
@inject IStringLocalizer<Localization> Loc;
<div @ref="Attachment" class="attachment" @onclick="Select" @onclick:stopPropagation="true">
@if (File.ContentType.StartsWith("image") || Constants.CommonImageExtensions.Any(e => File.Filename.EndsWith(e)))
{
<img class="thumbnail" src="@File.ThumbnailUrl" alt="@File.Description"/>
}
else if (File.ContentType.StartsWith("audio") || Constants.CommonAudioExtensions.Any(e => File.Filename.EndsWith(e)))
{
<Icon Name="Icons.FileAudio" Size="3em"/>
}
else if (File.ContentType.StartsWith("video") || Constants.CommonVideoExtensions.Any(e => File.Filename.EndsWith(e)))
{
<Icon Name="Icons.FileVideo" Size="3em"/>
}
else
{
<Icon Name="Icons.File" Size="3em"/>
}
@if (!File.ContentType.StartsWith("image") && Constants.CommonImageExtensions.All(e => !File.Filename.EndsWith(e)))
{
<span class="file-name">@File.Filename</span>
}
<div class="labels">
@if (File.Description != null)
{
<Icon Name="Icons.ClosedCaptioning" title="@File.Description"/>
}
else
{
<Icon Name="Icons.Warning" title="@Loc["No alt text"]"/>
}
@if (File.Sensitive)
{
<Icon Name="Icons.EyeSlash" title="@Loc["Sensitive"]"/>
}
</div>
<Menu @ref="AttachmentMenu">
<MenuElement Icon="Icons.ArrowSquareOut" OnSelect="Open">
<Text>@Loc["Open"]</Text>
</MenuElement>
@* TODO: Uncomment when FE supports media node *@
@* @if (File.ContentType.StartsWith("image")) *@
@* { *@
@* <MenuElement Icon="Icons.Paperclip" OnSelect="InsertInline"> *@
@* <Text>@Loc["Insert inline"]</Text> *@
@* </MenuElement> *@
@* } *@
@if (File.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>
}
<MenuElement Icon="Icons.ClosedCaptioning" OnSelect="SetAltText">
<Text>@Loc["Set alt text"]</Text>
</MenuElement>
<MenuElement Icon="Icons.Trash" OnSelect="Remove">
<Text>@Loc["Remove"]</Text>
</MenuElement>
<ClosingBackdrop OnClose="AttachmentMenu.Close"></ClosingBackdrop>
</Menu>
</div>
@code {
[Parameter, EditorRequired] public required DriveFileResponse File { get; set; }
[Parameter] [EditorRequired] public required EventCallback<string> AddInlineMedia { get; set; }
[Parameter, EditorRequired] public required EventCallback<string> RemoveAttachment { get; set; }
private ElementReference Attachment { get; set; }
private Menu AttachmentMenu { get; set; } = null!;
private void Select() => AttachmentMenu.Toggle(Attachment, false);
private void Open() => Js.InvokeVoidAsync("open", File.Url, "_blank");
// TODO: Uncomment when FE supports media node
// private async Task InsertInline()
// {
// if (!File.ContentType.StartsWith("image/")) return;
// await AddInlineMedia.InvokeAsync(File.Url);
// }
private async Task MarkSensitive(bool sensitive)
{
try
{
var res = await Api.Drive.UpdateFileAsync(File.Id, new UpdateDriveFileRequest { Sensitive = sensitive });
if (res != null)
{
File.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 SetAltText() =>
await Global.PromptDialog?.Prompt(new EventCallback<string?>(this, SetAltTextCallback), Loc["Set alt text"], "", File.Description, true, true)!;
private async Task SetAltTextCallback(string? alt)
{
if (alt == null) return;
try
{
var res = await Api.Drive.UpdateFileAsync(File.Id, new UpdateDriveFileRequest { Description = string.IsNullOrWhiteSpace(alt) ? null : alt });
if (res != null)
{
File.Description = res.Description;
StateHasChanged();
}
}
catch (ApiException e)
{
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!;
}
}
private async Task Remove() =>
await Global.ConfirmDialog?.Confirm(new EventCallback<bool>(this, RemoveCallback), Loc["Remove attachment?"], buttonText: Loc["Remove"])!;
private async Task RemoveCallback(bool remove)
{
if (remove) await RemoveAttachment.InvokeAsync(File.Id);
}
}