166 lines
No EOL
6.3 KiB
Text
166 lines
No EOL
6.3 KiB
Text
@using Iceshrimp.Assets.PhosphorIcons
|
|
@using Iceshrimp.Frontend.Core.Services
|
|
@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
|
|
|
|
<div class="note-footer">
|
|
@if (Reactions.Count > 0)
|
|
{
|
|
<div class="reactions">
|
|
@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.NoteResponse.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"/>
|
|
</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.NoteResponse.User.Id == Session.Current?.Id)
|
|
{
|
|
<MenuElement Icon="Icons.Trash" OnSelect="Note.Delete">
|
|
<Text>@Loc["Delete"]</Text>
|
|
</MenuElement>
|
|
<MenuElement Icon="Icons.Eraser" OnSelect="Note.Redraft">
|
|
<Text>@Loc["Redraft"]</Text>
|
|
</MenuElement>
|
|
}
|
|
else
|
|
{
|
|
<MenuElement Icon="Icons.Tooth" OnSelect="Note.Bite">
|
|
<Text>@Loc["Bite"]</Text>
|
|
</MenuElement>
|
|
}
|
|
<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>
|
|
<MenuElement Icon="Icons.SpeakerX" OnSelect="Note.Mute">
|
|
<Text>@Loc["Mute Note"]</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; }
|
|
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] Note Note { get; set; } = null!;
|
|
|
|
private void ToggleMenu() => ContextMenu.Toggle(MenuButton);
|
|
|
|
private void Delete() => _ = Note.Delete();
|
|
|
|
private void OpenOriginal() => Js.InvokeVoidAsync("open", Note.NoteResponse.Url, "_blank");
|
|
|
|
private void CopyLink() => Js.InvokeVoidAsync("navigator.clipboard.writeText", Note.NoteResponse.Url);
|
|
|
|
private void Like()
|
|
{
|
|
_ = Note.ToggleLike();
|
|
}
|
|
|
|
private void Reply()
|
|
{
|
|
Note.Reply();
|
|
}
|
|
|
|
private void ToggleRenoteMenu()
|
|
{
|
|
RenoteMenu.Toggle(RenoteButton);
|
|
}
|
|
|
|
private void Renote(NoteVisibility visibility)
|
|
{
|
|
_ = Note.Renote(visibility);
|
|
}
|
|
|
|
private void Quote()
|
|
{
|
|
Note.DoQuote();
|
|
}
|
|
|
|
private void ToggleEmojiPicker()
|
|
{
|
|
GlobalComponentSvc.EmojiPicker?.Open(EmojiButton, new EventCallback<EmojiResponse>(this, React));
|
|
}
|
|
|
|
private void React(EmojiResponse emoji)
|
|
{
|
|
Note.React(emoji);
|
|
}
|
|
} |