fix(channels): address R13 S3 review findings
- ActionMenu: skip disabled items in roving keyboard nav (plumb disabledIndices through the AnchoredPopover platform); a pending action no longer strands focus on an unfocusable button. - ActionMenu + ChannelStatsPopover: add type="button" to the popover triggers so they can't submit an enclosing form. - ChannelStatsPopover: restore the per-stat explanations as a native title on each row — the guidance the old inline stats showed is back. - i18n: drop the now-dead channels.tags.yourTags / .manage keys (en+hu); the stats *Hint keys are live again via the restored row titles. - test: cover ActionMenu (open/select/close/disabled) and ChannelStatsPopover (rows, conditional ETA row, per-row hint title).
This commit is contained in:
@@ -29,17 +29,26 @@ export default function ChannelStatsPopover({ status }: { status: MyStatus }) {
|
||||
offset: 8,
|
||||
});
|
||||
|
||||
const rows: { icon: LucideIcon; label: string; value: string | number }[] = [
|
||||
{ icon: Users, label: t("channels.stats.channels"), value: status.channels_total },
|
||||
// Each row keeps the per-stat explanation the old inline stats carried (as a native `title` on the
|
||||
// row), so hovering a figure still tells the user what it counts — the guidance is not lost.
|
||||
const rows: { icon: LucideIcon; label: string; value: string | number; hint: string }[] = [
|
||||
{
|
||||
icon: Users,
|
||||
label: t("channels.stats.channels"),
|
||||
value: status.channels_total,
|
||||
hint: t("channels.stats.channelsHint"),
|
||||
},
|
||||
{
|
||||
icon: RefreshCw,
|
||||
label: t("channels.stats.recentSynced"),
|
||||
value: `${status.channels_recent_synced}/${status.channels_total}`,
|
||||
hint: t("channels.stats.recentSyncedHint"),
|
||||
},
|
||||
{
|
||||
icon: History,
|
||||
label: t("channels.stats.fullHistory"),
|
||||
value: `${status.channels_deep_done}/${status.channels_deep_requested}`,
|
||||
hint: t("channels.stats.fullHistoryHint"),
|
||||
},
|
||||
...(status.deep_pending_count > 0
|
||||
? [
|
||||
@@ -47,20 +56,28 @@ export default function ChannelStatsPopover({ status }: { status: MyStatus }) {
|
||||
icon: Clock,
|
||||
label: t("channels.stats.left"),
|
||||
value: formatEta(status.deep_eta_seconds),
|
||||
hint: t("channels.stats.leftHint", { count: status.deep_pending_count }),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{ icon: Film, label: t("channels.stats.myVideos"), value: status.my_videos.toLocaleString() },
|
||||
{
|
||||
icon: Film,
|
||||
label: t("channels.stats.myVideos"),
|
||||
value: status.my_videos.toLocaleString(),
|
||||
hint: t("channels.stats.myVideosHint"),
|
||||
},
|
||||
{
|
||||
icon: Zap,
|
||||
label: t("channels.stats.quotaLeft"),
|
||||
value: status.quota_remaining_today.toLocaleString(),
|
||||
hint: t("channels.stats.quotaLeftHint"),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
ref={pop.refs.setReference}
|
||||
{...pop.getReferenceProps()}
|
||||
className="glass-card glass-hover inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-sm text-muted transition"
|
||||
@@ -74,7 +91,11 @@ export default function ChannelStatsPopover({ status }: { status: MyStatus }) {
|
||||
className="glass-menu w-60 rounded-xl p-2 text-xs animate-[popIn_0.16s_ease]"
|
||||
>
|
||||
{rows.map((r) => (
|
||||
<div key={r.label} className="flex items-center gap-2.5 px-1.5 py-1.5">
|
||||
<div
|
||||
key={r.label}
|
||||
title={r.hint}
|
||||
className="flex cursor-help items-center gap-2.5 px-1.5 py-1.5"
|
||||
>
|
||||
<r.icon className="h-4 w-4 shrink-0 text-muted" aria-hidden="true" />
|
||||
<span className="flex-1 text-muted">{r.label}</span>
|
||||
<span className="tabular-nums font-medium text-fg">{r.value}</span>
|
||||
|
||||
Reference in New Issue
Block a user