diff --git a/app/(auth)/(tabs)/(home)/_layout.tsx b/app/(auth)/(tabs)/(home)/_layout.tsx index 4005586c..8e313eaf 100644 --- a/app/(auth)/(tabs)/(home)/_layout.tsx +++ b/app/(auth)/(tabs)/(home)/_layout.tsx @@ -1,6 +1,6 @@ import { Chromecast } from "@/components/Chromecast"; import { nestedTabPageScreenOptions } from "@/components/stacks/NestedTabPageStack"; -import { Feather, Ionicons } from "@expo/vector-icons"; +import { Feather } from "@expo/vector-icons"; import { Stack, useRouter } from "expo-router"; import { Platform, TouchableOpacity, View } from "react-native"; @@ -55,6 +55,12 @@ export default function IndexLayout() { title: "", }} /> + {Object.entries(nestedTabPageScreenOptions).map(([name, options]) => ( ))} diff --git a/app/(auth)/(tabs)/(home)/settings.tsx b/app/(auth)/(tabs)/(home)/settings.tsx index 63d1b5c9..8f6d102a 100644 --- a/app/(auth)/(tabs)/(home)/settings.tsx +++ b/app/(auth)/(tabs)/(home)/settings.tsx @@ -6,6 +6,7 @@ import { DownloadSettings } from "@/components/settings/DownloadSettings"; import { MediaProvider } from "@/components/settings/MediaContext"; import { MediaToggles } from "@/components/settings/MediaToggles"; import { OtherSettings } from "@/components/settings/OtherSettings"; +import { PluginSettings } from "@/components/settings/PluginSettings"; import { QuickConnect } from "@/components/settings/QuickConnect"; import { StorageSettings } from "@/components/settings/StorageSettings"; import { SubtitleToggles } from "@/components/settings/SubtitleToggles"; @@ -63,15 +64,7 @@ export default function settings() { - - - router.push("/settings/jellyseerr/page")} - title={"Jellyseerr Settings"} - showArrow - > - - + diff --git a/app/(auth)/(tabs)/(home)/settings/marlin-search/page.tsx b/app/(auth)/(tabs)/(home)/settings/marlin-search/page.tsx new file mode 100644 index 00000000..b8255c6e --- /dev/null +++ b/app/(auth)/(tabs)/(home)/settings/marlin-search/page.tsx @@ -0,0 +1,103 @@ +import { Text } from "@/components/common/Text"; +import { ListGroup } from "@/components/list/ListGroup"; +import { ListItem } from "@/components/list/ListItem"; +import { apiAtom } from "@/providers/JellyfinProvider"; +import { useSettings } from "@/utils/atoms/settings"; +import { useQueryClient } from "@tanstack/react-query"; +import { useNavigation } from "expo-router"; +import { useAtom } from "jotai"; +import { useEffect, useState } from "react"; +import { + Linking, + Switch, + TextInput, + TouchableOpacity, + View, +} from "react-native"; +import { toast } from "sonner-native"; + +export default function page() { + const navigation = useNavigation(); + + const [settings, updateSettings] = useSettings(); + const queryClient = useQueryClient(); + + const [value, setValue] = useState(settings?.marlinServerUrl || ""); + + const onSave = (val: string) => { + updateSettings({ + marlinServerUrl: !val.endsWith("/") ? val : val.slice(0, -1), + }); + toast.success("Saved"); + }; + + const handleOpenLink = () => { + Linking.openURL("https://github.com/fredrikburmester/marlin-search"); + }; + + useEffect(() => { + navigation.setOptions({ + headerRight: () => ( + onSave(value)}> + Save + + ), + }); + }, [navigation, value]); + + if (!settings) return null; + + return ( + + + { + updateSettings({ searchEngine: "Jellyfin" }); + queryClient.invalidateQueries({ queryKey: ["search"] }); + }} + > + { + updateSettings({ searchEngine: value ? "Marlin" : "Jellyfin" }); + queryClient.invalidateQueries({ queryKey: ["search"] }); + }} + /> + + + + + + + URL + setValue(text)} + /> + + + + Enter the URL for the Marlin server. The URL should include http or + https and optionally the port.{" "} + + Read more about Marlin. + + + + + ); +} diff --git a/app/(auth)/(tabs)/(search)/index.tsx b/app/(auth)/(tabs)/(search)/index.tsx index a24a65f4..9f4ed6be 100644 --- a/app/(auth)/(tabs)/(search)/index.tsx +++ b/app/(auth)/(tabs)/(search)/index.tsx @@ -95,6 +95,8 @@ export default function search() { return (searchApi.data.SearchHints as BaseItemDto[]) || []; } else { if (!settings?.marlinServerUrl) return []; + + console.log(settings.marlinServerUrl); const url = `${ settings.marlinServerUrl }/search?q=${encodeURIComponent(query)}&includeItemTypes=${types @@ -102,6 +104,9 @@ export default function search() { .join("&includeItemTypes=")}`; const response1 = await axios.get(url); + + console.log(response1.statusText); + const ids = response1.data.ids; if (!ids || !ids.length) return []; diff --git a/components/settings/DownloadSettings.tsx b/components/settings/DownloadSettings.tsx index ba2ac493..f330dc04 100644 --- a/components/settings/DownloadSettings.tsx +++ b/components/settings/DownloadSettings.tsx @@ -5,13 +5,13 @@ import { Ionicons } from "@expo/vector-icons"; import { useQueryClient } from "@tanstack/react-query"; import { useRouter } from "expo-router"; import React from "react"; -import { Switch, TouchableOpacity } from "react-native"; +import { Switch, TouchableOpacity, View } from "react-native"; import * as DropdownMenu from "zeego/dropdown-menu"; import { Text } from "../common/Text"; import { ListGroup } from "../list/ListGroup"; import { ListItem } from "../list/ListItem"; -export const DownloadSettings: React.FC = () => { +export const DownloadSettings: React.FC = ({ ...props }) => { const [settings, updateSettings] = useSettings(); const { setProcesses } = useDownload(); const router = useRouter(); @@ -20,84 +20,92 @@ export const DownloadSettings: React.FC = () => { if (!settings) return null; return ( - - - - - - - {settings.downloadMethod === "remux" ? "Default" : "Optimized"} - - - - - - Methods - { - updateSettings({ downloadMethod: "remux" }); - setProcesses([]); - }} + + + + + + + + {settings.downloadMethod === "remux" + ? "Default" + : "Optimized"} + + + + + - Default - - { - updateSettings({ downloadMethod: "optimized" }); - setProcesses([]); - queryClient.invalidateQueries({ queryKey: ["search"] }); - }} - > - Optimized - - - - + Methods + { + updateSettings({ downloadMethod: "remux" }); + setProcesses([]); + }} + > + Default + + { + updateSettings({ downloadMethod: "optimized" }); + setProcesses([]); + queryClient.invalidateQueries({ queryKey: ["search"] }); + }} + > + Optimized + + + + - - - updateSettings({ - remuxConcurrentLimit: value as Settings["remuxConcurrentLimit"], - }) - } - /> - + + + updateSettings({ + remuxConcurrentLimit: value as Settings["remuxConcurrentLimit"], + }) + } + /> + - - updateSettings({ autoDownload: value })} - /> - + > + updateSettings({ autoDownload: value })} + /> + - router.push("/settings/optimized-server/page")} - showArrow - title="Optimized Versions Server" - > - + router.push("/settings/optimized-server/page")} + showArrow + title="Optimized Versions Server" + > + + ); }; diff --git a/components/settings/OtherSettings.tsx b/components/settings/OtherSettings.tsx index 5ec5d0df..318f54cd 100644 --- a/components/settings/OtherSettings.tsx +++ b/components/settings/OtherSettings.tsx @@ -1,11 +1,5 @@ -import { Stepper } from "@/components/inputs/Stepper"; -import { useDownload } from "@/providers/DownloadProvider"; import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; -import { - ScreenOrientationEnum, - Settings, - useSettings, -} from "@/utils/atoms/settings"; +import { ScreenOrientationEnum, useSettings } from "@/utils/atoms/settings"; import { BACKGROUND_FETCH_TASK, registerBackgroundFetchAsync, @@ -15,22 +9,13 @@ import { Ionicons } from "@expo/vector-icons"; import { getItemsApi } from "@jellyfin/sdk/lib/utils/api"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import * as BackgroundFetch from "expo-background-fetch"; -import { useRouter } from "expo-router"; import * as ScreenOrientation from "expo-screen-orientation"; import * as TaskManager from "expo-task-manager"; import { useAtom } from "jotai"; import React, { useEffect, useState } from "react"; -import { - Linking, - Switch, - TouchableOpacity, - View, - ViewProps, -} from "react-native"; +import { Linking, Switch, TouchableOpacity, ViewProps } from "react-native"; import { toast } from "sonner-native"; import * as DropdownMenu from "zeego/dropdown-menu"; -import { Button } from "../Button"; -import { Input } from "../common/Input"; import { Text } from "../common/Text"; import { ListGroup } from "../list/ListGroup"; import { ListItem } from "../list/ListItem"; @@ -76,6 +61,8 @@ export const OtherSettings: React.FC = () => { /********************** *********************/ + const queryClient = useQueryClient(); + const { data: mediaListCollections, isLoading: isLoadingMediaListCollections, @@ -258,129 +245,6 @@ export const OtherSettings: React.FC = () => { )} )} - - - - - - - {settings.searchEngine} - - - - - - Orientation - { - updateSettings({ - defaultVideoOrientation: - ScreenOrientation.OrientationLock.DEFAULT, - }); - }} - > - - { - ScreenOrientationEnum[ - ScreenOrientation.OrientationLock.DEFAULT - ] - } - - - { - updateSettings({ - defaultVideoOrientation: - ScreenOrientation.OrientationLock.PORTRAIT_UP, - }); - }} - > - - { - ScreenOrientationEnum[ - ScreenOrientation.OrientationLock.PORTRAIT_UP - ] - } - - - { - updateSettings({ - defaultVideoOrientation: - ScreenOrientation.OrientationLock.LANDSCAPE_LEFT, - }); - }} - > - - { - ScreenOrientationEnum[ - ScreenOrientation.OrientationLock.LANDSCAPE_LEFT - ] - } - - - { - updateSettings({ - defaultVideoOrientation: - ScreenOrientation.OrientationLock.LANDSCAPE_RIGHT, - }); - }} - > - - { - ScreenOrientationEnum[ - ScreenOrientation.OrientationLock.LANDSCAPE_RIGHT - ] - } - - - - - - - {settings.searchEngine === "Marlin" && ( - - - setMarlinUrl(text)} - /> - - - - )} - diff --git a/components/settings/PluginSettings.tsx b/components/settings/PluginSettings.tsx new file mode 100644 index 00000000..3df0171b --- /dev/null +++ b/components/settings/PluginSettings.tsx @@ -0,0 +1,30 @@ +import { useSettings } from "@/utils/atoms/settings"; +import { useRouter } from "expo-router"; +import React from "react"; +import { View } from "react-native"; +import { ListGroup } from "../list/ListGroup"; +import { ListItem } from "../list/ListItem"; + +export const PluginSettings = () => { + const [settings, updateSettings] = useSettings(); + + const router = useRouter(); + + if (!settings) return null; + return ( + + + router.push("/settings/jellyseerr/page")} + title={"Jellyseerr Settings"} + showArrow + /> + router.push("/settings/marlin-search/page")} + title="Marlin Search" + showArrow + /> + + + ); +};