193 lines
7.1 KiB
Text
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);
|
|
}
|
|
}
|