import type { MediaSourceInfo } from "@jellyfin/sdk/lib/generated-client/models"; import { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { Platform, TouchableOpacity, View } from "react-native"; import { Text } from "./common/Text"; import { type OptionGroup, PlatformOptionsMenu } from "./PlatformOptionsMenu"; interface Props extends React.ComponentProps { source?: MediaSourceInfo; onChange: (value: number) => void; selected?: number | undefined; } export const AudioTrackSelector: React.FC = ({ source, onChange, selected, ...props }) => { const isTv = Platform.isTV; const [open, setOpen] = useState(false); const { t } = useTranslation(); const audioStreams = useMemo( () => source?.MediaStreams?.filter((x) => x.Type === "Audio"), [source], ); const selectedAudioSteam = useMemo( () => audioStreams?.find((x) => x.Index === selected), [audioStreams, selected], ); const optionGroups: OptionGroup[] = useMemo( () => [ { id: "audio-streams", title: "Audio streams", options: audioStreams?.map((audio, idx) => ({ id: `${audio.Index || idx}`, type: "radio" as const, groupId: "audio-streams", label: audio.DisplayTitle || `Audio Stream ${idx + 1}`, selected: audio.Index === selected, })) || [], }, ], [audioStreams, selected], ); const handleOptionSelect = (optionId: string) => { const selectedStream = audioStreams?.find( (audio, idx) => `${audio.Index || idx}` === optionId, ); if ( selectedStream && selectedStream.Index !== null && selectedStream.Index !== undefined ) { onChange(selectedStream.Index); } setOpen(false); }; const trigger = ( {t("item_card.audio")} setOpen(true)} > {selectedAudioSteam?.DisplayTitle} ); if (isTv) return null; return ( ); };