fix(feed): size the compact row's columns for Hungarian too

Every width was measured in the English UI, but "101.7K megtekintés" is
139px against "101.7K views" at 79 — so a Hungarian user's view count
ellipsed itself in a column whose job is to show it. The channel column
gives back the room: its names truncate at any width we can afford (12
of 102 at 128 vs 5 at 160), and a clipped name still reads where a
clipped number does not.

The channel name also carries a tooltip now — it truncates hardest in
the fixed column and had no way to be read in full.
This commit is contained in:
2026-07-16 23:59:49 +02:00
parent 5433a60ac9
commit 7dda44c487
+17 -9
View File
@@ -365,6 +365,9 @@ function VideoCard({
e.stopPropagation();
onOpenChannel?.(video.channel_id, video.channel_title ?? t("card.thisChannel"));
}}
// The name truncates in every layout (hard in the one-line row's fixed column), so it always
// carries the full text — unlike the title, which only earns a tooltip once it's clamped.
title={video.channel_title ?? undefined}
className="text-sm text-muted truncate block w-fit max-w-full text-left hover:text-fg"
>
{video.channel_title}
@@ -390,13 +393,18 @@ function VideoCard({
// A table without being one. Every column is a FIXED width, which is what makes the same datum
// land on the same vertical line in every row — a CSS grid can't do it for us, because
// VirtualFeed renders each row as its own subtree, so there is no shared grid to align to.
// Widths come from measuring the real data at text-sm, then taking the next Tailwind step up:
// channel names run to 342px at worst (they truncate — most are far shorter), views peak at 79,
// the badges at 130 ("11:46:50" + a STREAM chip + the saved pip — the library really does hold
// 11-hour streams), "11 months ago · Feb 28, 2026" at 181, and the actions 188 (6 x 28 + 5 x 4).
// Size against the WORST case in the library, not a page of it: badges were sized 102 off a
// 60-video sample, which missed both the chips' own margins and any stream over two hours, and
// the column silently wrapped to a second line — in the one layout that promises single lines.
// Widths are measured, not chosen by eye — against the worst case in the LIBRARY and in BOTH
// languages, since both have caught me out here:
// actions 188 (6 x 28 + 5 x 4) · badges 130 ("11:46:50" + a STREAM chip + the saved pip —
// the library really does hold an 11-hour stream) · views 139 ("101.7K megtekintés"; the
// English "views" is only 79) · published 183 ("11 months ago · Feb 28, 2026"; HU is
// shorter) · channel 128, which is a deliberate cut rather than a fit: names run to 342px,
// the median is 87, and 12 of 102 truncate here vs 5 at 160 — worth 32px to the title, since
// a clipped channel name still reads while a clipped view count loses the number.
// Two ways this went wrong before, both worth avoiding: sizing off a PAGE of data (badges came
// from 60 videos whose longest was 2:00:58, and the column then wrapped in the one layout that
// promises single lines), and measuring with a hand-built probe instead of the real element
// (that read "101.7K megtekintés" as 122px when the live cell renders it at 139).
// The title takes what's left, which is constant per container width — so it aligns too.
if (noThumb) {
const pct = resumePct(video);
@@ -406,11 +414,11 @@ function VideoCard({
they're the shortest pointer trip from it. */}
<div className="shrink-0 w-48">{actions}</div>
<div className="min-w-0 flex-1">{title}</div>
<div className="shrink-0 w-40">{channelButton}</div>
<div className="shrink-0 w-32">{channelButton}</div>
<div className="shrink-0 w-36 text-sm text-muted">
<InlineBadges video={video} />
</div>
<div className="shrink-0 w-24 text-sm text-muted truncate">{views}</div>
<div className="shrink-0 w-36 text-sm text-muted truncate">{views}</div>
<div className="shrink-0 w-48 text-sm text-muted truncate">{published}</div>
{/* Thumb draws this over the image; with no image it goes on the row itself. */}
{pct > 0 && (