refactor(feed): derive the row's drop-out thresholds from its column widths
They were two hand-written sets of numbers describing the same boxes — change a w-32 and the thresholds are silently wrong, the symptom being a column appearing just before it fits. Now computed from one table (which reproduces the old values exactly). Width also stops reaching the four views that ignore it: it changes every frame of a resize, so passing it everywhere pushed all of them through VideoCard's memo for nothing.
This commit is contained in:
@@ -322,15 +322,33 @@ function Thumb({
|
||||
);
|
||||
}
|
||||
|
||||
// What the one-line row needs before each column earns its place, cumulative from the left:
|
||||
// actions (192) + a title worth reading (~120) + gaps + the row's padding, then each column plus
|
||||
// its gap. Driven by the ROW's measured width, never the viewport — see VirtualFeed's itemWidth.
|
||||
const ROW_FITS = {
|
||||
channel: 490,
|
||||
meta: 606,
|
||||
views: 682,
|
||||
published: 886,
|
||||
};
|
||||
// The one-line row's column widths, in ONE place — the Tailwind classes below are generated from
|
||||
// them, so the thresholds can't drift out of step with the boxes they describe (they did when both
|
||||
// were written by hand). Each is measured against the worst case in the library AND in both
|
||||
// languages; see the row's own comment for where each number comes from.
|
||||
const ROW_COL = {
|
||||
actions: 192, // w-48 — six buttons at 28 + five 4px gaps = 188
|
||||
title: 120, // — not a column: the floor below which a title isn't worth showing
|
||||
channel: 128, // w-32
|
||||
meta: 104, // — RowMetaCells' own grid: 4rem + 1rem + 1rem + two 4px gaps
|
||||
views: 64, // w-16
|
||||
published: 192, // w-48
|
||||
} as const;
|
||||
const ROW_GAP = 12; // gap-3
|
||||
const ROW_PAD = 26; // px-3 both sides, plus a rounding allowance
|
||||
|
||||
// What the row must measure before each column earns its place — cumulative from the left, so each
|
||||
// one only appears once everything ahead of it AND a readable title already fit.
|
||||
const ROW_FITS = (() => {
|
||||
let w = ROW_PAD + ROW_COL.actions + ROW_GAP + ROW_COL.title;
|
||||
const at = (px: number) => (w += ROW_GAP + px);
|
||||
return {
|
||||
channel: at(ROW_COL.channel),
|
||||
meta: at(ROW_COL.meta),
|
||||
views: at(ROW_COL.views),
|
||||
published: at(ROW_COL.published),
|
||||
};
|
||||
})();
|
||||
|
||||
function VideoCard({
|
||||
video,
|
||||
|
||||
@@ -180,7 +180,11 @@ export default function VirtualFeed({
|
||||
key={v.id}
|
||||
video={v}
|
||||
view={view}
|
||||
width={itemWidth}
|
||||
// Only the one-line row reads its own width (it stands columns down as it
|
||||
// narrows). Everything else takes a stable 0, so a resize — which changes
|
||||
// itemWidth every frame — doesn't blow past VideoCard's memo for views that
|
||||
// wouldn't do anything with it.
|
||||
width={FEED_VIEW_SPEC[view].thumb ? 0 : itemWidth}
|
||||
onState={onState}
|
||||
onToggleSave={onToggleSave}
|
||||
onOpenChannel={onOpenChannel}
|
||||
|
||||
Reference in New Issue
Block a user