House rules: numbers through one formatter, no made-up server errors, and the rules fail the build
Build / Build (push) Successful in 33s
Build / Build (push) Successful in 33s
- Every number shown on a page goes through NumbersExtensions: counts, percentages, the nerd readouts and the values written into a style. - A failure the client builds itself (offline, timeout, retries run out, an answer it can't read) is a 400 that names its kind; only a server's own 5XX passes through. - Login, sign-up, recovery and password confirmations leave autocomplete to the browser, so it can offer the saved login. - The Daisy components start with empty lists and attributes, and a decorative image still renders alt="". - Arasaka.HouseRules.Analyzers checks all of this in every build, together with PrivaPub.ClientModels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W4YtEJrgxG12Pc39Fai8Bd
This commit is contained in:
1 parent
697b2c8897
commit
3827d903a3
37 files changed
+165
-111
No files matched your search
@@ -804,7 +804,7 @@
|
||||
var option = poll.Options[i];
|
||||
var share = poll.VotesCount > 0 && option.VotesCount is { } votes ? votes * 100d / poll.VotesCount : 0;
|
||||
<div class="relative rounded-md overflow-hidden neo-inset neo-2xs px-2 py-1">
|
||||
<div class="absolute inset-y-0 left-0 bg-primary/20" style="width:@(share.ToString("0.#", System.Globalization.CultureInfo.InvariantCulture))%"></div>
|
||||
<div class="absolute inset-y-0 left-0 bg-primary/20" style="width:@(share.ToCssNumber())%"></div>
|
||||
<span class="relative flex justify-between gap-2">
|
||||
<span>
|
||||
@option.Title
|
||||
@@ -813,7 +813,7 @@
|
||||
<i class="ion-md-checkmark-circle text-primary" title="@Localizer["Your vote"]" aria-label="@Localizer["Your vote"]"></i>
|
||||
}
|
||||
</span>
|
||||
<span>@share.ToString("0")%</span>
|
||||
<span>@share.ToWholePercent()</span>
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
@@ -1318,7 +1318,7 @@
|
||||
|
||||
// where a cropped picture keeps its subject: Mastodon's focus runs from -1 to 1, left to right and bottom to top
|
||||
static string FocalPoint(MediaAttachment media) => media.Meta?.Focus is { } focus
|
||||
? string.Create(System.Globalization.CultureInfo.InvariantCulture, $"object-position: {(focus.X + 1) * 50:0.#}% {(1 - focus.Y) * 50:0.#}%")
|
||||
? string.Create(System.Globalization.CultureInfo.InvariantCulture, $"object-position: {((focus.X + 1) * 50).ToCssNumber()}% {((1 - focus.Y) * 50).ToCssNumber()}%")
|
||||
: null;
|
||||
|
||||
static bool IsWebLink(string url) => Uri.TryCreate(url, UriKind.Absolute, out var uri) && uri.Scheme is "https" or "http";
|
||||
@@ -1474,7 +1474,7 @@
|
||||
yield return NerdRow.Of(Localizer["server"], server.NodeName is { Length: > 0 } name && name != server.Host ? $"{server.Host} ({name})" : server.Host);
|
||||
yield return NerdRow.Of(Localizer["software"], $"{server.Software} {server.Version}".Trim());
|
||||
yield return NerdRow.Of(Localizer["Users"], server.Users is { } users
|
||||
? server.ActiveMonth is { } active ? $"{users:N0} ({active:N0} {Localizer["active this month"]})" : users.ToString("N0")
|
||||
? server.ActiveMonth is { } active ? $"{users.ToDefaultCount()} ({active.ToDefaultCount()} {Localizer["active this month"]})" : users.ToDefaultCount()
|
||||
: null);
|
||||
yield return NerdRow.Of(Localizer["local posts"], server.LocalPosts);
|
||||
yield return NerdRow.Of(Localizer["registrations"], server.OpenRegistrations is { } open ? open ? Localizer["open"] : Localizer["closed"] : null);
|
||||
@@ -1553,7 +1553,7 @@
|
||||
_ => Localizer["Near you"]
|
||||
});
|
||||
yield return NerdRow.Of("lat, lng", $"{Coordinate(location.Latitude)}, {Coordinate(location.Longitude)}");
|
||||
yield return NerdRow.Of(Localizer["precision"], $"±{location.PrecisionKm:0} km");
|
||||
yield return NerdRow.Of(Localizer["precision"], $"±{location.PrecisionKm.ToDefaultCount()} km");
|
||||
if (location.Source is LocationSource.Server or LocationSource.Country && ServerGeo is { } geo)
|
||||
{
|
||||
yield return NerdRow.Of(Localizer["network"], geo.Network);
|
||||
@@ -1561,7 +1561,7 @@
|
||||
yield return NerdRow.Of(Localizer["located at"], geo.LocatedAt);
|
||||
}
|
||||
if (InstanceService.Known(InstanceService.SelfHost)?.Geo is { Latitude: { } selfLatitude, Longitude: { } selfLongitude } && location.Source is not LocationSource.NearYou)
|
||||
yield return new(Localizer["from PrivaPub"], $"{NerdRow.Kilometres(selfLatitude, selfLongitude, location.Latitude, location.Longitude):N0} km");
|
||||
yield return new(Localizer["from PrivaPub"], $"{NerdRow.Kilometres(selfLatitude, selfLongitude, location.Latitude, location.Longitude).ToDefaultCount()} km");
|
||||
}
|
||||
|
||||
static IEnumerable<NerdRow> MediaRows(MediaAttachment media)
|
||||
@@ -1570,7 +1570,7 @@
|
||||
yield return NerdRow.Of("size", media.Meta?.Original?.Size);
|
||||
yield return NerdRow.Of("aspect", media.Meta?.Original?.Aspect);
|
||||
yield return NerdRow.Of("length", media.Meta?.Length);
|
||||
yield return NerdRow.Of("focus", media.Meta?.Focus is { } focus ? $"{focus.X:0.##}, {focus.Y:0.##}" : null);
|
||||
yield return NerdRow.Of("focus", media.Meta?.Focus is { } focus ? $"{focus.X.ToReadout()}, {focus.Y.ToReadout()}" : null);
|
||||
yield return NerdRow.Of("blurhash", media.Blurhash);
|
||||
yield return NerdRow.Of("served by", Uri.TryCreate(media.Url, UriKind.Absolute, out var served) ? served.Host : null);
|
||||
yield return NerdRow.Of("origin", Uri.TryCreate(media.RemoteUrl, UriKind.Absolute, out var origin) ? origin.Host : null);
|
||||
|
||||
Reference in new issue
Block a user