"use client"; import { Badge, Box, Group, ScrollArea, SimpleGrid, Stack, Text } from "@mantine/core"; import { getQueryKey } from "@trpc/react-query"; import { clientApi } from "@homarr/api/client"; import { formatBytes, formatDuration } from "@homarr/common"; import type { AudiobookshelfDashboardData } from "@homarr/integrations/types"; import { WidgetEmptyState } from "../common/empty-state"; import { IntegrationErrorIndicator } from "../common/integration-error-indicator"; import type { WidgetComponentProps } from "../definition"; import { useWidgetRuntimeQueries } from "../runtime-hooks"; import { AudioStatsContent } from "./audio-stats-content"; export default function AudioStatsWidget({ integrationIds, options, width, height, displayScale = 1, displayMode = "compact", widgetRuntimeRef, }: WidgetComponentProps<"audioStats">) { const statsInput = { integrationId: integrationIds[0] ?? "" }; const { data: response, error: statsError } = clientApi.widget.audioStats.getStats.useQuery(statsInput); const streamsInput = { integrationIds: [statsInput.integrationId], showOnlyPlaying: true }; const streamsEnabled = displayMode === "advanced" && response?.kind === "navidrome"; const { data: streamResults, error: streamsError } = clientApi.widget.mediaServer.getCurrentStreams.useQuery( streamsInput, { enabled: streamsEnabled }, ); useWidgetRuntimeQueries(widgetRuntimeRef, [ getQueryKey(clientApi.widget.audioStats.getStats, statsInput, "query"), ...(streamsEnabled ? [getQueryKey(clientApi.widget.mediaServer.getCurrentStreams, streamsInput, "query")] : []), ]); if (statsError && response === undefined) throw statsError; if (streamsEnabled && streamsError && streamResults === undefined) throw streamsError; const currentStreams = streamResults ?? []; if (!response) return ; let responsiveWidth = width; let responsiveHeight = height; if (displayMode === "compact" && Number.isFinite(displayScale) && displayScale > 0) { responsiveWidth *= displayScale; responsiveHeight *= displayScale; } const summary = ( ); if (displayMode === "compact") { return ( {summary} ); } const sessions = currentStreams.flatMap((result) => result.sessions.map((session) => ({ integrationId: result.integrationId, session })), ); const audiobookStats = response.kind === "audiobookshelf" ? (response.data as AudiobookshelfDashboardData) : null; const advancedGridColumns = width >= 760 ? 2 : 1; const hasStreamErrors = currentStreams.some(({ error }) => Boolean(error)); return (
{summary}
{hasStreamErrors && ( )} {response.kind === "navidrome" ? ( {sessions.map(({ integrationId, session }) => { const currentlyPlaying = session.currentlyPlaying; if (!currentlyPlaying) return null; return ( {currentlyPlaying.name} {currentlyPlaying.seasonName ?? currentlyPlaying.albumName ?? session.user?.username ?? "โ€”"} {session.sessionName} ); })} ) : ( {(audiobookStats?.libraries ?? []).map((library) => ( {library.name} {library.totalItems} {library.totalDurationSeconds === null ? "โ€”" : formatDuration(library.totalDurationSeconds * 1000)} ยท{" "} {library.totalSizeBytes === null ? "โ€”" : formatBytes(library.totalSizeBytes)} ))} )}
); }