diff --git a/app/(auth)/(tabs)/(home)/settings.tv.tsx b/app/(auth)/(tabs)/(home)/settings.tv.tsx
index eb73ec56..ae84f5b3 100644
--- a/app/(auth)/(tabs)/(home)/settings.tv.tsx
+++ b/app/(auth)/(tabs)/(home)/settings.tv.tsx
@@ -3,7 +3,7 @@ import { SubtitlePlaybackMode } from "@jellyfin/sdk/lib/generated-client";
import { useAtom } from "jotai";
import React, { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
-import { Animated, Pressable, ScrollView, View } from "react-native";
+import { Animated, Pressable, ScrollView, TextInput, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Text } from "@/components/common/Text";
import type { TVOptionItem } from "@/components/tv";
@@ -301,6 +301,81 @@ const TVSettingsOptionButton: React.FC<{
);
};
+// TV-optimized text input component
+const TVSettingsTextInput: React.FC<{
+ label: string;
+ value: string;
+ placeholder?: string;
+ onChangeText: (text: string) => void;
+ onBlur?: () => void;
+ secureTextEntry?: boolean;
+ disabled?: boolean;
+}> = ({
+ label,
+ value,
+ placeholder,
+ onChangeText,
+ onBlur,
+ secureTextEntry,
+ disabled,
+}) => {
+ const { focused, handleFocus, handleBlur, animatedStyle } =
+ useTVFocusAnimation({ scaleAmount: 1.02 });
+
+ const handleInputBlur = () => {
+ handleBlur();
+ onBlur?.();
+ };
+
+ return (
+
+
+
+ {label}
+
+
+
+
+ );
+};
+
// Section header component
const SectionHeader: React.FC<{ title: string }> = ({ title }) => (
(null);
+ // Local state for OpenSubtitles API key (only commit on blur)
+ const [openSubtitlesApiKey, setOpenSubtitlesApiKey] = useState(
+ settings.openSubtitlesApiKey || "",
+ );
+
const currentAudioTranscode =
settings.audioTranscodeMode || AudioTranscodeMode.Auto;
const currentSubtitleMode =
@@ -641,6 +721,50 @@ export default function SettingsTV() {
disabled={isModalOpen}
/>
+ {/* OpenSubtitles Section */}
+
+
+ {t("home.settings.subtitles.opensubtitles_hint") ||
+ "Enter your OpenSubtitles API key to enable client-side subtitle search as a fallback when your Jellyfin server doesn't have a subtitle provider configured."}
+
+ updateSettings({ openSubtitlesApiKey })}
+ secureTextEntry
+ disabled={isModalOpen}
+ />
+
+ {t("home.settings.subtitles.opensubtitles_get_key") ||
+ "Get your free API key at opensubtitles.com/en/consumers"}
+
+
{/* Appearance Section */}