import { Badge, Box, Group, Paper, Progress, Stack, Text, Tooltip } from "@mantine/core";
import { IconPlayerPause, IconPlayerPlay } from "@tabler/icons-react";
import { formatDuration } from "@homarr/common";
import type { TracearrStream } from "@homarr/integrations/types";
import { useScopedI18n } from "@homarr/translation/client";
export function StreamsList({ streams, width }: { streams: TracearrStream[]; width: number }) {
const t = useScopedI18n("widget.tracearr");
if (streams.length === 0) {
return (
{t("streams.empty")}
);
}
return (
{streams.map((stream) => (
))}
);
}
function StreamCard({ stream, compact }: { stream: TracearrStream; compact: boolean }) {
const t = useScopedI18n("widget.tracearr");
const progressPercent =
stream.durationMs && stream.durationMs > 0 ? (stream.progressMs / stream.durationMs) * 100 : 0;
const mediaLabel =
stream.mediaType === "episode" && stream.showTitle
? `${stream.showTitle} - S${stream.seasonNumber ?? 0}E${stream.episodeNumber ?? 0} - ${stream.mediaTitle}`
: stream.mediaTitle;
const videoDecisionLabel =
stream.videoDecision === "directplay"
? t("streams.videoDecision.directPlay")
: stream.videoDecision === "transcode"
? t("streams.videoDecision.transcode")
: stream.videoDecision === "copy"
? t("streams.videoDecision.directStream")
: null;
return (
{stream.posterUrl && (
)}
{stream.state === "playing" ? (
) : (
)}
{stream.username}
{stream.resolution && (
{stream.resolution}
)}
{videoDecisionLabel && (
{videoDecisionLabel}
)}
{mediaLabel}
{stream.durationMs && stream.durationMs > 0 && (
{formatDuration(stream.progressMs)} / {formatDuration(stream.durationMs)}
)}
{stream.device && (
{stream.player ?? stream.device}
)}
);
}