Refactor plugin metadata handling in streaming cards

Moves plugin metadata fetching from StreamingSessionCard to ActiveStreamsCard and passes the data as a prop. Defines PluginMetaResponse type in types/streaming.ts for better type safety and reusability.
This commit is contained in:
Christopher
2025-12-15 22:02:59 -07:00
parent 266036101f
commit 98de143521
3 changed files with 18 additions and 15 deletions

View File

@@ -1,7 +1,8 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { StreamingSessionCard } from './StreamingSessionCard';
import type { ActiveSession, ActiveSessionsResponse, ViewMode } from '@/types/streaming';
import { useAdminApi } from '@/hooks/useAdminApi';
import type { ActiveSession, ActiveSessionsResponse, PluginMetaResponse, ViewMode } from '@/types/streaming';
interface ActiveStreamsCardProps {
sessionsData: ActiveSessionsResponse | null;
@@ -24,11 +25,15 @@ export const ActiveStreamsCard = ({
lastUpdateAt,
onTerminateSession
}: ActiveStreamsCardProps) => {
const { data: pluginMetaData } = useAdminApi<PluginMetaResponse>('/plugins/metadata', true);
const pluginFeaturesByService = pluginMetaData?.data ?? null;
const renderSessionCard = (session: ActiveSession) => (
<StreamingSessionCard
key={session.session_key}
session={session}
onTerminate={onTerminateSession}
pluginFeaturesByService={pluginFeaturesByService}
/>
);

View File

@@ -14,11 +14,10 @@ import { Textarea } from '@/components/ui/textarea';
import { requestJson } from '@/util/apiClient';
import { useAlerts } from '@/contexts/AlertContext';
import { getServiceIconClass, getServiceMeta } from '@/config/pluginMetadata';
import { useAdminApi } from '@/hooks/useAdminApi';
import { useState } from 'react';
import { useNavigate } from '@tanstack/react-router';
import { buildUserProfilePath } from '@/util/routes';
import type { ActiveSession } from '@/types/streaming';
import type { ActiveSession, PluginMetaResponse } from '@/types/streaming';
const StreamInfoDialog = ({ open, onOpenChange }: { open: boolean; onOpenChange: (open: boolean) => void }) => {
return (
@@ -80,6 +79,7 @@ const StreamInfoDialog = ({ open, onOpenChange }: { open: boolean; onOpenChange:
interface StreamingSessionCardProps {
session: ActiveSession;
onTerminate: (session: ActiveSession) => void;
pluginFeaturesByService?: PluginMetaResponse['data'] | null;
}
const getStateColor = (state?: string) => {
@@ -90,15 +90,6 @@ const getStateColor = (state?: string) => {
return 'text-gray-500 bg-gray-500';
};
type PluginMetaResponse = {
data: Record<
string,
{
features?: string[];
}
>;
};
type JellyfinRawSession = {
UserId?: string;
PlayState?: { AudioStreamIndex?: number };
@@ -183,14 +174,13 @@ const tryExtractJellyfinUserId = (rawDataJson?: string) => {
}
};
export const StreamingSessionCard = ({ session, onTerminate }: StreamingSessionCardProps) => {
export const StreamingSessionCard = ({ session, onTerminate, pluginFeaturesByService }: StreamingSessionCardProps) => {
const [showStreamInfo, setShowStreamInfo] = useState(false);
const [showSendMessage, setShowSendMessage] = useState(false);
const [sendMessageText, setSendMessageText] = useState('');
const [sendMessageHeader, setSendMessageHeader] = useState('MUM');
const [sendMessageTimeoutSeconds, setSendMessageTimeoutSeconds] = useState<string>('');
const [sendingMessage, setSendingMessage] = useState(false);
const { data: pluginMetaData } = useAdminApi<PluginMetaResponse>('/plugins/metadata', true);
const navigate = useNavigate();
const normalizedState = session.state?.toLowerCase();
const stateColor = getStateColor(session.state);
@@ -205,7 +195,7 @@ export const StreamingSessionCard = ({ session, onTerminate }: StreamingSessionC
const serviceMeta = getServiceMeta(session.service_type);
const supportsSessionMessage = Boolean(
normalizedServiceType &&
pluginMetaData?.data?.[normalizedServiceType]?.features?.includes('session_message')
pluginFeaturesByService?.[normalizedServiceType]?.features?.includes('session_message')
);
const jellyfinAudioTranscodeLabel =

View File

@@ -71,3 +71,11 @@ export type ActiveSessionsResponse = {
export type ViewMode = 'merged' | 'categorized' | 'service';
export type PluginMetaResponse = {
data: Record<
string,
{
features?: string[];
}
>;
};