Iceshrimp.NET/Iceshrimp.Frontend/Components/Note/NoteFooter.razor

193 lines
7.1 KiB
Text

@using Iceshrimp.Assets.PhosphorIcons
@using Iceshrimp.Frontend.Core.Services
@using Iceshrimp.Frontend.Core.Services.NoteStore
@using Iceshrimp.Frontend.Localization
@using Iceshrimp.Shared.Schemas.Web
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<Localization> Loc;
@inject IJSRuntime Js;
@inject SessionService Session;
@inject GlobalComponentSvc GlobalComponentSvc
@inject NoteActions NoteActions;
<div class="note-footer">
@if (Reactions.Count > 0)
{
<div class="reactions @(Indented ? "indent" : "")">
@foreach (var reaction in Reactions)
{
<NoteReaction Reaction="reaction"/>
}
</div>
}
<button class="btn" @onclick="Reply" @onclick:stopPropagation="true" aria-label="reply">
<Icon Name="Icons.ArrowUUpLeft" Size="1.3em"/>
@if (Replies > 0)
{
<span class="reply-count">@Replies</span>
}
</button>
<button @ref="RenoteButton" class="btn @(RenotePossible ? "" : "disabled")"
@onclick="@(RenotePossible ? ToggleRenoteMenu : () => { })" @onclick:stopPropagation="true"
aria-label="renote">
@if (RenotePossible)
{
<Icon Name="Icons.Repeat" Size="1.3em"/>
<Menu @ref="RenoteMenu">
@if (Note.Visibility == NoteVisibility.Public)
{
<MenuElement Icon="Icons.Repeat" OnSelect="() => Renote(NoteVisibility.Public)">
<Text>@Loc["Renote"]</Text>
</MenuElement>
}
<MenuElement Icon="Icons.House" OnSelect="() => Renote(NoteVisibility.Home)">
<Text>@Loc["Renote (Unlisted)"]</Text>
</MenuElement>
<MenuElement Icon="Icons.Lock" OnSelect="() => Renote(NoteVisibility.Followers)">
<Text>@Loc["Renote (Followers)"]</Text>
</MenuElement>
<ClosingBackdrop OnClose="RenoteMenu.Close"></ClosingBackdrop>
</Menu>
}
else
{
<Icon Name="Icons.Lock" Size="1.3em" class="faded"/>
}
@if (Renotes > 0)
{
<span class="renote-count">@Renotes</span>
}
</button>
<button @onclick="Like" @onclick:stopPropagation="true" class="btn" aria-label="like">
@if (IsLiked)
{
<Icon Name="Icons.Heart" Pack="IconStyle.Fill" Size="1.3em"/>
}
else
{
<Icon Name="Icons.Heart" Size="1.3em"/>
}
@if (Likes > 0)
{
<span class="like-count">@Likes</span>
}
</button>
<button @ref="EmojiButton" class="btn" @onclick="ToggleEmojiPicker" @onclick:stopPropagation="true"
aria-label="emoji picker">
<Icon Name="Icons.Smiley" Size="1.3em"/>
@if (Reactions.Count > 0)
{
<span class="like-count">@Reactions.Sum(r => r.Count)</span>
}
</button>
<button class="btn" @onclick="Quote" @onclick:stopPropagation="true" aria-label="quote">
<Icon Name="Icons.Quotes" Size="1.3em"/>
</button>
<button @ref="MenuButton" class="btn" @onclick="ToggleMenu" @onclick:stopPropagation="true" aria-label="more">
<Icon Name="Icons.DotsThreeOutline" Size="1.3em"/>
<Menu @ref="ContextMenu">
@if (Note.User.Id != Session.Current?.Id)
{
<MenuElement Icon="Icons.Tooth" OnSelect="Bite">
<Text>@Loc["Bite"]</Text>
</MenuElement>
}
<MenuElement Icon="Icons.SpeakerX" OnSelect="Mute">
<Text>@Loc["Mute thread"]</Text>
</MenuElement>
<hr class="rule"/>
<MenuElement Icon="Icons.ArrowSquareOut" OnSelect="OpenOriginal">
<Text>@Loc["Open original page"]</Text>
</MenuElement>
<MenuElement Icon="Icons.Share" OnSelect="CopyLink">
<Text>@Loc["Copy link"]</Text>
</MenuElement>
@if (Note.User.Id == Session.Current?.Id)
{
<hr class="rule"/>
<MenuElement Icon="Icons.Eraser" OnSelect="Redraft" Danger>
<Text>@Loc["Delete & redraft"]</Text>
</MenuElement>
<MenuElement Icon="Icons.Trash" OnSelect="Delete" Danger>
<Text>@Loc["Delete"]</Text>
</MenuElement>
}
<ClosingBackdrop OnClose="ContextMenu.Close"></ClosingBackdrop>
</Menu>
</button>
</div>
@code {
[Parameter] [EditorRequired] public required List<NoteReactionSchema> Reactions { get; set; }
[Parameter] [EditorRequired] public required int Likes { get; set; }
[Parameter] [EditorRequired] public required bool IsLiked { get; set; }
[Parameter] [EditorRequired] public required int Renotes { get; set; }
[Parameter] [EditorRequired] public required int Replies { get; set; }
[Parameter] public bool RenotePossible { get; set; }
[Parameter] public bool Indented { get; set; }
private Menu ContextMenu { get; set; } = null!;
private Menu RenoteMenu { get; set; } = null!;
private ElementReference RenoteButton { get; set; }
private ElementReference EmojiButton { get; set; }
private ElementReference MenuButton { get; set; }
[CascadingParameter] NoteBase Note { get; set; } = null!;
private void ToggleMenu() => ContextMenu.Toggle(MenuButton);
private void Delete() => _ = NoteActions.DeleteAsync(Note);
private void OpenOriginal() => Js.InvokeVoidAsync("open", Note.Url, "_blank");
private void CopyLink() => Js.InvokeVoidAsync("navigator.clipboard.writeText", Note.Url);
private void Like()
{
_ = NoteActions.ToggleLikeAsync(Note);
}
private void Reply()
{
NoteActions.Reply(Note);
}
private void ToggleRenoteMenu()
{
RenoteMenu.Toggle(RenoteButton);
}
private void Renote(NoteVisibility visibility)
{
_ = NoteActions.RenoteAsync(Note);
}
private void Quote()
{
NoteActions.DoQuote(Note);
}
private void ToggleEmojiPicker()
{
GlobalComponentSvc.EmojiPicker?.Open(EmojiButton, new EventCallback<EmojiResponse>(this, React));
}
private void React(EmojiResponse emoji)
{
NoteActions.React(Note, emoji);
}
private void Redraft()
{
_ = NoteActions.RedraftAsync(Note);
}
private void Bite()
{
_ = NoteActions.BiteAsync(Note);
}
private void Mute()
{
_ = NoteActions.MuteAsync(Note);
}
}