112 lines
5.4 KiB
Plaintext
112 lines
5.4 KiB
Plaintext
<aside @ref="LogPanelRef" class="card log-panel">
|
|
<div class="section-head">
|
|
<h2>Campaign Log</h2>
|
|
</div>
|
|
<div @ref="LogFeedRef" class="log-panel-feed">
|
|
@if (IsCampaignDataLoading)
|
|
{
|
|
<div class="skeleton-stack">
|
|
<div class="skeleton-line"></div>
|
|
<div class="skeleton-line"></div>
|
|
<div class="skeleton-line short"></div>
|
|
</div>
|
|
}
|
|
else if (CampaignLog.Count == 0)
|
|
{
|
|
<p class="empty">No log entries yet.</p>
|
|
}
|
|
else
|
|
{
|
|
<ul class="log-list">
|
|
@foreach (var entry in CampaignLog)
|
|
{
|
|
var isExpanded = ExpandedRollId == entry.RollId;
|
|
<li class="log-entry @LogEntryCssClass(entry, isExpanded, FreshRollId == entry.RollId)">
|
|
<button type="button"
|
|
class="log-entry-toggle"
|
|
aria-expanded="@isExpanded"
|
|
@onclick="() => ToggleRollDetailRequested.InvokeAsync(entry.RollId)">
|
|
<span class="log-entry-main">
|
|
<span class="log-entry-copy">
|
|
<span class="log-entry-actor">@entry.RollerLabel</span>
|
|
<span class="log-entry-action">rolled</span>
|
|
<span class="log-entry-skill">@entry.SkillName</span>
|
|
<span class="log-entry-action">with</span>
|
|
<span class="log-entry-character">@entry.CharacterName</span>
|
|
</span>
|
|
<span class="roll-total inline">@entry.Result</span>
|
|
</span>
|
|
@if (HasSummary(entry))
|
|
{
|
|
<span class="log-summary-row">
|
|
@foreach (var badge in GetEventBadges(entry))
|
|
{
|
|
<span class="log-event-badge @badge.Tone">@badge.Label</span>
|
|
}
|
|
@if (!string.IsNullOrWhiteSpace(entry.SummaryText))
|
|
{
|
|
<span class="log-summary-text">@entry.SummaryText</span>
|
|
}
|
|
</span>
|
|
}
|
|
<span class="log-meta">
|
|
<span class="badge @entry.VisibilityStyle">@entry.VisibilityLabel</span>
|
|
<time
|
|
title="@entry.TimestampUtc.ToString("O")">
|
|
@entry.TimestampUtc.ToLocalTime().ToString("g")
|
|
</time>
|
|
</span>
|
|
</button>
|
|
@if (isExpanded)
|
|
{
|
|
<div class="log-detail">
|
|
@if (IsRollDetailLoading(entry.RollId))
|
|
{
|
|
<p class="muted">Loading roll detail...</p>
|
|
}
|
|
else if (!string.IsNullOrWhiteSpace(GetRollDetailError(entry.RollId)))
|
|
{
|
|
<p class="field-error">@GetRollDetailError(entry.RollId)</p>
|
|
}
|
|
else if (ResolveRollDetail(entry.RollId) is { } detail)
|
|
{
|
|
<RollDiceStrip Dice="detail.Dice" AriaLabel="Log roll dice"/>
|
|
<p>@detail.Breakdown</p>
|
|
}
|
|
</div>
|
|
}
|
|
</li>
|
|
}
|
|
</ul>
|
|
}
|
|
</div>
|
|
|
|
<section class="custom-roll-panel" aria-label="Custom roll panel">
|
|
<form class="custom-roll-composer" @onsubmit="SubmitCustomRollAsync" @onsubmit:preventDefault>
|
|
<div class="custom-roll-composer-head">
|
|
<label for="custom-roll-expression" class="custom-roll-label">Custom roll</label>
|
|
<span class="muted">@CustomRollStatusText</span>
|
|
</div>
|
|
<div class="custom-roll-composer-row">
|
|
<input id="custom-roll-expression"
|
|
@key="CustomRollInputVersion"
|
|
@ref="CustomRollInputRef"
|
|
class="@CustomRollInputCssClass"
|
|
@bind="CustomRollExpression"
|
|
@bind:event="oninput"
|
|
placeholder="@CustomRollPlaceholder"
|
|
title="@CustomRollInputTitle"
|
|
aria-invalid="@HasCustomRollError"
|
|
aria-describedby="@CustomRollInputDescribedBy"
|
|
disabled="@IsCustomRollDisabled"/>
|
|
<button type="submit" disabled="@IsCustomRollDisabled">Roll</button>
|
|
</div>
|
|
<p class="field-help">@CustomRollHelpText</p>
|
|
@if (HasCustomRollError)
|
|
{
|
|
<p id="@CustomRollErrorElementId" class="field-error" role="alert">@CustomRollErrorMessage</p>
|
|
}
|
|
</form>
|
|
</section>
|
|
</aside>
|