feat(card): show LIVE/upcoming badge where duration is absent
Live streams and upcoming/premiere videos have no fixed duration, so the playlist row and video card left a blank where the runtime usually sits. Show a LIVE (red) or upcoming badge instead, so it's clear the missing time is by design, not a sync gap.
This commit is contained in:
parent
15811b8b43
commit
d42a038a3f
5 changed files with 29 additions and 4 deletions
|
|
@ -110,6 +110,7 @@ function Row({
|
||||||
onPlay: () => void;
|
onPlay: () => void;
|
||||||
onRemove: () => void;
|
onRemove: () => void;
|
||||||
}) {
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { attributes, listeners, setNodeRef, transform, transition, isDragging } =
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } =
|
||||||
useSortable({ id: video.id, disabled: readOnly });
|
useSortable({ id: video.id, disabled: readOnly });
|
||||||
const style = {
|
const style = {
|
||||||
|
|
@ -151,11 +152,21 @@ function Row({
|
||||||
<div className="text-[13px] text-fg truncate">{video.title}</div>
|
<div className="text-[13px] text-fg truncate">{video.title}</div>
|
||||||
<div className="text-[11px] text-muted truncate">{video.channel_title}</div>
|
<div className="text-[11px] text-muted truncate">{video.channel_title}</div>
|
||||||
</button>
|
</button>
|
||||||
{video.duration_seconds != null && (
|
{video.duration_seconds != null ? (
|
||||||
<span className="text-[11px] text-muted tabular-nums">
|
<span className="text-[11px] text-muted tabular-nums">
|
||||||
{formatDuration(video.duration_seconds)}
|
{formatDuration(video.duration_seconds)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
) : video.live_status === "live" || video.live_status === "upcoming" ? (
|
||||||
|
<span
|
||||||
|
className={`text-[10px] font-semibold uppercase tracking-wide px-1.5 py-0.5 rounded ${
|
||||||
|
video.live_status === "live"
|
||||||
|
? "bg-red-500/90 text-white"
|
||||||
|
: "bg-card border border-border text-muted"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{t(`card.${video.live_status}`)}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
{!readOnly && (
|
{!readOnly && (
|
||||||
<button
|
<button
|
||||||
onClick={onRemove}
|
onClick={onRemove}
|
||||||
|
|
|
||||||
|
|
@ -154,11 +154,19 @@ function Thumb({
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-full" />
|
<div className="w-full h-full" />
|
||||||
)}
|
)}
|
||||||
{video.duration_seconds != null && (
|
{video.duration_seconds != null ? (
|
||||||
<span className="absolute bottom-1.5 right-1.5 bg-black/80 text-white text-[11px] font-medium px-1.5 py-0.5 rounded">
|
<span className="absolute bottom-1.5 right-1.5 bg-black/80 text-white text-[11px] font-medium px-1.5 py-0.5 rounded">
|
||||||
{formatDuration(video.duration_seconds)}
|
{formatDuration(video.duration_seconds)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
) : video.live_status === "live" || video.live_status === "upcoming" ? (
|
||||||
|
<span
|
||||||
|
className={`absolute bottom-1.5 right-1.5 text-[10px] font-semibold uppercase tracking-wide px-1.5 py-0.5 rounded ${
|
||||||
|
video.live_status === "live" ? "bg-red-500/90 text-white" : "bg-black/80 text-white"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{t(`card.${video.live_status}`)}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
{video.live_status === "was_live" && (
|
{video.live_status === "was_live" && (
|
||||||
<span className="absolute top-1.5 left-1.5 bg-accent text-accent-fg text-[10px] font-semibold uppercase tracking-wide px-1.5 py-0.5 rounded">
|
<span className="absolute top-1.5 left-1.5 bg-accent text-accent-fg text-[10px] font-semibold uppercase tracking-wide px-1.5 py-0.5 rounded">
|
||||||
{t("card.stream")}
|
{t("card.stream")}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"live": "live",
|
||||||
|
"upcoming": "demnächst",
|
||||||
"watchedUnmark": "Angesehen — zum Aufheben klicken",
|
"watchedUnmark": "Angesehen — zum Aufheben klicken",
|
||||||
"markWatched": "Als angesehen markieren",
|
"markWatched": "Als angesehen markieren",
|
||||||
"savedRemove": "Gespeichert — zum Entfernen klicken",
|
"savedRemove": "Gespeichert — zum Entfernen klicken",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"live": "live",
|
||||||
|
"upcoming": "upcoming",
|
||||||
"watchedUnmark": "Watched — click to unmark",
|
"watchedUnmark": "Watched — click to unmark",
|
||||||
"markWatched": "Mark watched",
|
"markWatched": "Mark watched",
|
||||||
"savedRemove": "Saved — click to remove",
|
"savedRemove": "Saved — click to remove",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"live": "élő",
|
||||||
|
"upcoming": "hamarosan",
|
||||||
"watchedUnmark": "Megnézve — kattints a visszavonáshoz",
|
"watchedUnmark": "Megnézve — kattints a visszavonáshoz",
|
||||||
"markWatched": "Megnézettnek jelöl",
|
"markWatched": "Megnézettnek jelöl",
|
||||||
"savedRemove": "Mentve — kattints az eltávolításhoz",
|
"savedRemove": "Mentve — kattints az eltávolításhoz",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue