diff --git a/app/(auth)/(tabs)/(home)/settings.tv.tsx b/app/(auth)/(tabs)/(home)/settings.tv.tsx
index a4bc7774..1734ee40 100644
--- a/app/(auth)/(tabs)/(home)/settings.tv.tsx
+++ b/app/(auth)/(tabs)/(home)/settings.tv.tsx
@@ -7,7 +7,8 @@ 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";
-import { TVOptionSelector, useTVFocusAnimation } from "@/components/tv";
+import { useTVFocusAnimation } from "@/components/tv";
+import { useTVOptionModal } from "@/hooks/useTVOptionModal";
import { apiAtom, useJellyfin, userAtom } from "@/providers/JellyfinProvider";
import { AudioTranscodeMode, useSettings } from "@/utils/atoms/settings";
@@ -112,7 +113,7 @@ const TVSettingsToggle: React.FC<{
width: 56,
height: 32,
borderRadius: 16,
- backgroundColor: value ? "#7c3aed" : "#4B5563",
+ backgroundColor: value ? "#34C759" : "#4B5563",
justifyContent: "center",
paddingHorizontal: 2,
}}
@@ -195,16 +196,20 @@ const TVSettingsStepper: React.FC<{
style={[
minusAnim.animatedStyle,
{
- width: 40,
- height: 40,
- borderRadius: 20,
- backgroundColor: minusAnim.focused ? "#7c3aed" : "#4B5563",
+ width: 48,
+ height: 36,
+ borderRadius: 18,
+ backgroundColor: minusAnim.focused ? "#FFFFFF" : "#4B5563",
justifyContent: "center",
alignItems: "center",
},
]}
>
-
+
-
+
@@ -371,7 +380,7 @@ const TVSettingsTextInput: React.FC<{
paddingVertical: 12,
paddingHorizontal: 16,
borderWidth: focused ? 2 : 1,
- borderColor: focused ? "#7c3aed" : "#4B5563",
+ borderColor: focused ? "#FFFFFF" : "#4B5563",
}}
/>
@@ -450,14 +459,6 @@ const TVLogoutButton: React.FC<{ onPress: () => void; disabled?: boolean }> = ({
);
};
-// Modal type for tracking open bottom sheets
-type SettingsModalType =
- | "audioTranscode"
- | "subtitleMode"
- | "alignX"
- | "alignY"
- | null;
-
export default function SettingsTV() {
const { t } = useTranslation();
const insets = useSafeAreaInsets();
@@ -465,9 +466,7 @@ export default function SettingsTV() {
const { logout } = useJellyfin();
const [user] = useAtom(userAtom);
const [api] = useAtom(apiAtom);
-
- // Modal state for option selectors
- const [openModal, setOpenModal] = useState(null);
+ const { showOptions } = useTVOptionModal();
// Local state for OpenSubtitles API key (only commit on blur)
const [openSubtitlesApiKey, setOpenSubtitlesApiKey] = useState(
@@ -592,18 +591,9 @@ export default function SettingsTV() {
return option?.label || "Bottom";
}, [alignYOptions]);
- const isModalOpen = openModal !== null;
-
return (
-
+
setOpenModal("audioTranscode")}
+ onPress={() =>
+ showOptions({
+ title: t("home.settings.audio.transcode_mode.title"),
+ options: audioTranscodeModeOptions,
+ onSelect: (value) =>
+ updateSettings({ audioTranscodeMode: value }),
+ })
+ }
isFirst
- disabled={isModalOpen}
/>
{/* Subtitles Section */}
@@ -640,8 +636,13 @@ export default function SettingsTV() {
setOpenModal("subtitleMode")}
- disabled={isModalOpen}
+ onPress={() =>
+ showOptions({
+ title: t("home.settings.subtitles.subtitle_mode"),
+ options: subtitleModeOptions,
+ onSelect: (value) => updateSettings({ subtitleMode: value }),
+ })
+ }
/>
updateSettings({ rememberSubtitleSelections: value })
}
- disabled={isModalOpen}
/>
`${v.toFixed(1)}x`}
- disabled={isModalOpen}
/>
{/* MPV Subtitles Section */}
@@ -690,7 +689,6 @@ export default function SettingsTV() {
});
}}
formatValue={(v) => `${v.toFixed(1)}x`}
- disabled={isModalOpen}
/>
setOpenModal("alignX")}
- disabled={isModalOpen}
+ onPress={() =>
+ showOptions({
+ title: "Horizontal Alignment",
+ options: alignXOptions,
+ onSelect: (value) =>
+ updateSettings({
+ mpvSubtitleAlignX: value as "left" | "center" | "right",
+ }),
+ })
+ }
/>
setOpenModal("alignY")}
- disabled={isModalOpen}
+ onPress={() =>
+ showOptions({
+ title: "Vertical Alignment",
+ options: alignYOptions,
+ onSelect: (value) =>
+ updateSettings({
+ mpvSubtitleAlignY: value as "top" | "center" | "bottom",
+ }),
+ })
+ }
/>
{/* OpenSubtitles Section */}
@@ -754,7 +767,6 @@ export default function SettingsTV() {
onChangeText={setOpenSubtitlesApiKey}
onBlur={() => updateSettings({ openSubtitlesApiKey })}
secureTextEntry
- disabled={isModalOpen}
/>
updateSettings({ mergeNextUpAndContinueWatching: value })
}
- disabled={isModalOpen}
/>
updateSettings({ showHomeBackdrop: value })}
- disabled={isModalOpen}
/>
{/* User Section */}
@@ -793,62 +803,19 @@ export default function SettingsTV() {
label={t("home.settings.user_info.user")}
value={user?.Name || "-"}
showChevron={false}
- disabled={isModalOpen}
/>
{/* Logout Button */}
-
+
-
- {/* Bottom sheet modals using shared TVOptionSelector */}
- updateSettings({ audioTranscodeMode: value })}
- onClose={() => setOpenModal(null)}
- />
-
- updateSettings({ subtitleMode: value })}
- onClose={() => setOpenModal(null)}
- />
-
-
- updateSettings({
- mpvSubtitleAlignX: value as "left" | "center" | "right",
- })
- }
- onClose={() => setOpenModal(null)}
- />
-
-
- updateSettings({
- mpvSubtitleAlignY: value as "top" | "center" | "bottom",
- })
- }
- onClose={() => setOpenModal(null)}
- />
);
}