99 lines
No EOL
3.6 KiB
Text
99 lines
No EOL
3.6 KiB
Text
@using Iceshrimp.Frontend.Core.Miscellaneous
|
|
@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 GlobalComponentSvc Global;
|
|
@inject NoteActions NoteActions;
|
|
@inject IStringLocalizer<Localization> Loc;
|
|
|
|
<div class="poll">
|
|
@if (CanVote())
|
|
{
|
|
<div class="poll-options">
|
|
@foreach (var (choice, i) in Poll.Choices.Select((c, i) => (c, i)))
|
|
{
|
|
<span class="poll-option">
|
|
@if (Poll.Multiple)
|
|
{
|
|
<input type="checkbox" @onchange="() => SelectMultiple(i)" id="option-@i" name="poll" checked="@choice.Voted" disabled="@choice.Voted"/>
|
|
}
|
|
else
|
|
{
|
|
<input type="radio" @onchange="() => SelectSingle(i)" id="option-@i" name="poll"/>
|
|
}
|
|
<label for="option-@i">
|
|
<MfmText Text="@choice.Value" Emoji="@Emoji" Simple="true"/>
|
|
</label>
|
|
</span>
|
|
}
|
|
<button class="button" @onclick="Vote" disabled="@(Choices.Count == 0)">@Loc["Vote"]</button>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="poll-results">
|
|
@{ var total = Poll.Choices.Sum(p => p.Votes); }
|
|
@foreach (var choice in Poll.Choices)
|
|
{
|
|
var percentage = total == 0 ? 0 : Math.Floor(choice.Votes / (double)total * 100);
|
|
|
|
<span class="poll-result @(choice.Voted ? "voted" : "")" style="--percentage: @percentage%;">
|
|
<span class="poll-value">
|
|
<MfmText Text="@choice.Value" Emoji="@Emoji" Simple="true"/>
|
|
</span>
|
|
<span class="poll-info"><span class="vote-count">@Loc["{0} votes", choice.Votes]</span><span class="vote-percentage">@percentage%</span></span>
|
|
</span>
|
|
}
|
|
</div>
|
|
}
|
|
@{
|
|
List<string> footerText = [];
|
|
@if (Poll.Multiple)
|
|
footerText.Add(Loc["Multiple choice"]);
|
|
@if (Poll.VotersCount != null)
|
|
footerText.Add(Loc["{0} users voted", Poll.VotersCount]);
|
|
@if (Poll.ExpiresAt != null)
|
|
footerText.Add(Poll.ExpiresAt <= DateTime.UtcNow ? Loc["Ended"] : Loc["Ends at {0}", Poll.ExpiresAt.Value.ToLocalTime().ToString("G")]);
|
|
}
|
|
<span class="poll-footer">@string.Join(" - ", footerText)</span>
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter, EditorRequired] public required NotePollSchema Poll { get; set; }
|
|
[Parameter, EditorRequired] public required List<EmojiResponse> Emoji { get; set; }
|
|
private List<int> Choices { get; set; } = [];
|
|
|
|
private bool CanVote()
|
|
{
|
|
return !Poll.Choices.Any(p => p.Voted) && (Poll.ExpiresAt == null || Poll.ExpiresAt > DateTime.UtcNow);
|
|
}
|
|
|
|
private void SelectMultiple(int choice)
|
|
{
|
|
if (Choices.Contains(choice))
|
|
Choices.RemoveAll(p => p == choice);
|
|
else
|
|
Choices.Add(choice);
|
|
}
|
|
|
|
private void SelectSingle(int choice)
|
|
{
|
|
Choices = [choice];
|
|
}
|
|
|
|
private async Task Vote()
|
|
{
|
|
if (!CanVote()) return;
|
|
|
|
try
|
|
{
|
|
await NoteActions.AddPollVoteAsync(Poll, Choices);
|
|
}
|
|
catch (ApiException e)
|
|
{
|
|
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred while voting"], NoticeDialog.NoticeType.Error)!;
|
|
}
|
|
}
|
|
} |