using System.Globalization; using Blog.Models; using Blog.Services; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Options; namespace Blog.Components.Pages; public partial class Rvrb : ComponentBase { [Inject] public required RvrbService Service { get; set; } [Inject] public required IOptions Settings { get; set; } private RvrbStatus Status { get; set; } = RvrbStatus.Unreachable("not read yet"); private RvrbSnapshot? Snapshot => Status.Snapshot; private RvrbOptions Options => Settings.Value; /// /// How stale the snapshot is by the time it reaches the browser. Snapshots are cached and /// shared, so the track that was 40 seconds in when it was taken is further along by now — this /// is what lets the page pick the counter up where the bot left it. /// private TimeSpan Age => DateTimeOffset.UtcNow - Status.FetchedAt; private string StatusLabel => Status switch { { Snapshot: null } => "offline", { Snapshot.Live: null } => "up, not in the room", _ => "up, in the room" }; private string StatusClass => Status switch { { Snapshot: null } => "status-down", { Snapshot.Live: null } => "status-idle", _ => "status-up" }; protected override async Task OnInitializedAsync() { Status = await Service.GetStatusAsync().ConfigureAwait(true); await base.OnInitializedAsync().ConfigureAwait(true); } /// The hover label on a bar: which day it is, and what it counts. private static string BarTitle(RvrbDay day) => $"{day.Date:yyyy-MM-dd}: {day.Plays} plays"; /// /// The weekday under a bar, so a fortnight of counts reads as weeks rather than as a row of /// numbers. Invariant rather than the request's culture: the rest of the page is in English, /// and a per-visitor abbreviation would change how wide the column has to be. /// private static string DayLabel(RvrbDay day) => day.Date.ToString("ddd", CultureInfo.InvariantCulture); /// /// A day's bar height as a percentage of the busiest day in the window, floored at something /// visible so a day with one play doesn't render as nothing at all. /// private int BarHeight(int plays) { if (plays == 0) return 0; var busiest = Snapshot?.PlaysPerDay.Max(day => day.Plays) ?? 0; return busiest == 0 ? 0 : Math.Max(4, (int)Math.Round(plays * 100.0 / busiest)); } }