diff --git a/frontend/src/components/PlexBrowse.tsx b/frontend/src/components/PlexBrowse.tsx
index 9a7f341..82bdf25 100644
--- a/frontend/src/components/PlexBrowse.tsx
+++ b/frontend/src/components/PlexBrowse.tsx
@@ -26,6 +26,7 @@ import {
type PlexSeasonDetail,
type PlexUnifiedResult,
} from "../lib/api";
+import { formatRuntime } from "../lib/format";
import { useDebounced } from "../lib/useDebounced";
import { useHistorySubview } from "../lib/history";
import { DetailCustomizeMenu, Filterable, useArtBackdrop, useDetailPrefs } from "../lib/plexDetailUi";
@@ -67,13 +68,6 @@ type Props = {
const PAGE = 40;
-function dur(n?: number | null): string {
- if (!n) return "";
- const h = Math.floor(n / 3600);
- const m = Math.floor((n % 3600) / 60);
- return h ? `${h}h ${m}m` : `${m}m`;
-}
-
export default function PlexBrowse({
q,
onClearSearch,
@@ -483,7 +477,7 @@ function PlexPosterCard({
style={{ background: "color-mix(in srgb, var(--card) 60%, transparent)" }}
>
{card.title}
- {[card.year, dur(card.duration_seconds)].filter(Boolean).join(" · ")}
+ {[card.year, formatRuntime(card.duration_seconds)].filter(Boolean).join(" · ")}
);
@@ -526,7 +520,8 @@ function PlexInfoView({
onPlay={onPlay}
onPlayItem={onPlayItem}
onFilter={onFilter}
- onStateChange={() => q.refetch()}
+ // No onStateChange: PlexInfo.setState already invalidates ["plex-item", id] (this very
+ // query), so q refetches automatically — a manual refetch here just double-fetched.
/>
)}
@@ -845,7 +840,7 @@ function EpisodeCard({
{!withShowTitle && {ep.episode_number}.}
{ep.title}
- {dur(ep.duration_seconds)}
+ {formatRuntime(ep.duration_seconds)}
{onAdd && (