From 6c051f6f610c94fe9d2e23f6aafd4787f3adfd16 Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Wed, 9 Oct 2024 07:49:22 +0200 Subject: [PATCH] first commit --- app/(auth)/(tabs)/(home)/_layout.tsx | 8 ++- .../(tabs)/(home)/settings/audio-language.tsx | 61 ++++++++++++++++++ .../{settings.tsx => settings/index.tsx} | 57 ++++++++++++++--- .../(home)/settings/subtitle-language.tsx | 61 ++++++++++++++++++ components/ListItem.tsx | 35 ---------- components/_page_template.tsx | 22 +++++++ components/list/ListInputItem.tsx | 64 +++++++++++++++++++ components/list/ListItem.tsx | 44 +++++++++++++ components/list/ListSection.tsx | 24 +++++++ components/settings/SettingToggles.tsx | 4 +- 10 files changed, 332 insertions(+), 48 deletions(-) create mode 100644 app/(auth)/(tabs)/(home)/settings/audio-language.tsx rename app/(auth)/(tabs)/(home)/{settings.tsx => settings/index.tsx} (72%) create mode 100644 app/(auth)/(tabs)/(home)/settings/subtitle-language.tsx delete mode 100644 components/ListItem.tsx create mode 100644 components/_page_template.tsx create mode 100644 components/list/ListInputItem.tsx create mode 100644 components/list/ListItem.tsx create mode 100644 components/list/ListSection.tsx diff --git a/app/(auth)/(tabs)/(home)/_layout.tsx b/app/(auth)/(tabs)/(home)/_layout.tsx index f51ecbf5..daa19f4d 100644 --- a/app/(auth)/(tabs)/(home)/_layout.tsx +++ b/app/(auth)/(tabs)/(home)/_layout.tsx @@ -42,11 +42,17 @@ export default function IndexLayout() { }} /> + {Object.entries(nestedTabPageScreenOptions).map(([name, options]) => ( ))} diff --git a/app/(auth)/(tabs)/(home)/settings/audio-language.tsx b/app/(auth)/(tabs)/(home)/settings/audio-language.tsx new file mode 100644 index 00000000..40f133bd --- /dev/null +++ b/app/(auth)/(tabs)/(home)/settings/audio-language.tsx @@ -0,0 +1,61 @@ +import { ScrollView, View, ViewProps } from "react-native"; +import { Text } from "@/components/common/Text"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import { LANGUAGES } from "@/constants/Languages"; +import { ListItem } from "@/components/list/ListItem"; +import { ListSection } from "@/components/list/ListSection"; +import { TAB_HEIGHT } from "@/constants/Values"; +import { DefaultLanguageOption, useSettings } from "@/utils/atoms/settings"; +import { Ionicons } from "@expo/vector-icons"; +import { Colors } from "@/constants/Colors"; + +interface Props extends ViewProps {} + +export default function page() { + const insets = useSafeAreaInsets(); + const [settings, updateSettings] = useSettings(); + return ( + + + + {LANGUAGES.sort(sortByName).map((l) => ( + { + updateSettings({ + ...settings, + defaultAudioLanguage: l, + }); + }} + iconAfter={ + settings?.defaultAudioLanguage?.value === l.value ? ( + + ) : null + } + /> + ))} + + + + ); +} + +const sortByName = (a: DefaultLanguageOption, b: DefaultLanguageOption) => { + if (a.label < b.label) { + return -1; + } + if (a.label > b.label) { + return 1; + } + return 0; +}; diff --git a/app/(auth)/(tabs)/(home)/settings.tsx b/app/(auth)/(tabs)/(home)/settings/index.tsx similarity index 72% rename from app/(auth)/(tabs)/(home)/settings.tsx rename to app/(auth)/(tabs)/(home)/settings/index.tsx index 6c5cc32a..887c9857 100644 --- a/app/(auth)/(tabs)/(home)/settings.tsx +++ b/app/(auth)/(tabs)/(home)/settings/index.tsx @@ -1,13 +1,18 @@ import { Button } from "@/components/Button"; import { Text } from "@/components/common/Text"; -import { ListItem } from "@/components/ListItem"; +import { ListInputItem } from "@/components/list/ListInputItem"; +import { ListItem } from "@/components/list/ListItem"; +import { ListSection } from "@/components/list/ListSection"; import { SettingToggles } from "@/components/settings/SettingToggles"; import { useDownload } from "@/providers/DownloadProvider"; import { apiAtom, useJellyfin, userAtom } from "@/providers/JellyfinProvider"; +import { useSettings } from "@/utils/atoms/settings"; import { clearLogs, readFromLog } from "@/utils/log"; +import { Ionicons } from "@expo/vector-icons"; import { getQuickConnectApi } from "@jellyfin/sdk/lib/utils/api"; import { useQuery } from "@tanstack/react-query"; import * as Haptics from "expo-haptics"; +import { useRouter } from "expo-router"; import { useAtom } from "jotai"; import { Alert, ScrollView, View } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; @@ -16,6 +21,7 @@ import { toast } from "sonner-native"; export default function settings() { const { logout } = useJellyfin(); const { deleteAllFiles } = useDownload(); + const [settings, updateSettings] = useSettings(); const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); @@ -57,6 +63,8 @@ export default function settings() { ); }; + const router = useRouter(); + return ( registerBackgroundFetchAsync */} - - User Info + + + + + - - - - - - + + + } + onPress={() => router.push("/settings/audio-language")} + /> + + } + onPress={() => router.push("/settings/subtitle-language")} + /> + { + // 1. validate positive number + // 2. save settings + if (val.length === 0) return; + if (val.match(/^\d+$/)) { + } else { + toast.error("Invalid number"); + } + }} + /> + Quick connect diff --git a/app/(auth)/(tabs)/(home)/settings/subtitle-language.tsx b/app/(auth)/(tabs)/(home)/settings/subtitle-language.tsx new file mode 100644 index 00000000..bf9fdf7e --- /dev/null +++ b/app/(auth)/(tabs)/(home)/settings/subtitle-language.tsx @@ -0,0 +1,61 @@ +import { ScrollView, View, ViewProps } from "react-native"; +import { Text } from "@/components/common/Text"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import { LANGUAGES } from "@/constants/Languages"; +import { ListItem } from "@/components/list/ListItem"; +import { ListSection } from "@/components/list/ListSection"; +import { TAB_HEIGHT } from "@/constants/Values"; +import { DefaultLanguageOption, useSettings } from "@/utils/atoms/settings"; +import { Ionicons } from "@expo/vector-icons"; +import { Colors } from "@/constants/Colors"; + +interface Props extends ViewProps {} + +export default function page() { + const insets = useSafeAreaInsets(); + const [settings, updateSettings] = useSettings(); + return ( + + + + {LANGUAGES.sort(sortByName).map((l) => ( + { + updateSettings({ + ...settings, + defaultSubtitleLanguage: l, + }); + }} + iconAfter={ + settings?.defaultSubtitleLanguage?.value === l.value ? ( + + ) : null + } + /> + ))} + + + + ); +} + +const sortByName = (a: DefaultLanguageOption, b: DefaultLanguageOption) => { + if (a.label < b.label) { + return -1; + } + if (a.label > b.label) { + return 1; + } + return 0; +}; diff --git a/components/ListItem.tsx b/components/ListItem.tsx deleted file mode 100644 index 755f79ed..00000000 --- a/components/ListItem.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { PropsWithChildren, ReactNode } from "react"; -import { View, ViewProps } from "react-native"; -import { Text } from "./common/Text"; - -interface Props extends ViewProps { - title?: string | null | undefined; - subTitle?: string | null | undefined; - children?: ReactNode; - iconAfter?: ReactNode; -} - -export const ListItem: React.FC> = ({ - title, - subTitle, - iconAfter, - children, - ...props -}) => { - return ( - - - {title} - {subTitle && ( - - {subTitle} - - )} - - {iconAfter} - - ); -}; diff --git a/components/_page_template.tsx b/components/_page_template.tsx new file mode 100644 index 00000000..76639f00 --- /dev/null +++ b/components/_page_template.tsx @@ -0,0 +1,22 @@ +import { ScrollView, View, ViewProps } from "react-native"; +import { Text } from "@/components/common/Text"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import { TAB_HEIGHT } from "@/constants/Values"; + +interface Props extends ViewProps {} + +export default function page() { + const insets = useSafeAreaInsets(); + return ( + + ); +} diff --git a/components/list/ListInputItem.tsx b/components/list/ListInputItem.tsx new file mode 100644 index 00000000..2916774f --- /dev/null +++ b/components/list/ListInputItem.tsx @@ -0,0 +1,64 @@ +import { PropsWithChildren, ReactNode, useEffect, useState } from "react"; +import { + Pressable, + TextInput, + TextInputProps, + TouchableOpacity, + TouchableOpacityProps, + View, + ViewProps, +} from "react-native"; +import { Text } from "../common/Text"; + +interface Props extends ViewProps { + title?: string | null | undefined; + text?: string | null | undefined; + children?: ReactNode; + iconAfter?: ReactNode; + iconBefore?: ReactNode; + textInputProps?: TextInputProps; + defaultValue?: string; + onChange: (text: string) => void; +} + +export const ListInputItem: React.FC> = ({ + title, + text, + iconAfter, + iconBefore, + children, + onChange, + textInputProps, + defaultValue, + ...props +}) => { + const [value, setValue] = useState(defaultValue || ""); + + useEffect(() => { + onChange(value); + }, [value]); + + return ( + + {iconBefore && {iconBefore}} + + {title} + + + + + {iconAfter && {iconAfter}} + + ); +}; diff --git a/components/list/ListItem.tsx b/components/list/ListItem.tsx new file mode 100644 index 00000000..76db0c8d --- /dev/null +++ b/components/list/ListItem.tsx @@ -0,0 +1,44 @@ +import { PropsWithChildren, ReactNode, useState } from "react"; +import { + Pressable, + TouchableOpacity, + TouchableOpacityProps, + View, + ViewProps, +} from "react-native"; +import { Text } from "../common/Text"; + +interface Props extends TouchableOpacityProps { + title?: string | null | undefined; + text?: string | null | undefined; + children?: ReactNode; + iconAfter?: ReactNode; + iconBefore?: ReactNode; +} + +export const ListItem: React.FC> = ({ + title, + text, + iconAfter, + iconBefore, + children, + ...props +}) => { + return ( + + {iconBefore && {iconBefore}} + + {title} + + + + {text} + + + {iconAfter && {iconAfter}} + + ); +}; diff --git a/components/list/ListSection.tsx b/components/list/ListSection.tsx new file mode 100644 index 00000000..f8acfb1e --- /dev/null +++ b/components/list/ListSection.tsx @@ -0,0 +1,24 @@ +import { View, ViewProps } from "react-native"; +import { Text } from "@/components/common/Text"; +import { Children, PropsWithChildren } from "react"; + +interface Props extends ViewProps { + title: string; +} + +export const ListSection: React.FC> = ({ + children, + title, + ...props +}) => { + return ( + + + {title} + + + {children} + + + ); +}; diff --git a/components/settings/SettingToggles.tsx b/components/settings/SettingToggles.tsx index 0688226a..f44f9d10 100644 --- a/components/settings/SettingToggles.tsx +++ b/components/settings/SettingToggles.tsx @@ -10,6 +10,7 @@ import { registerBackgroundFetchAsync, unregisterBackgroundFetchAsync, } from "@/utils/background-tasks"; +import { getStatistics } from "@/utils/optimize-server"; import { getItemsApi } from "@jellyfin/sdk/lib/utils/api"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import * as BackgroundFetch from "expo-background-fetch"; @@ -18,7 +19,6 @@ import * as TaskManager from "expo-task-manager"; import { useAtom } from "jotai"; import { useEffect, useState } from "react"; import { - ActivityIndicator, Linking, Switch, TouchableOpacity, @@ -32,8 +32,6 @@ import { Input } from "../common/Input"; import { Text } from "../common/Text"; import { Loader } from "../Loader"; import { MediaToggles } from "./MediaToggles"; -import axios from "axios"; -import { getStatistics } from "@/utils/optimize-server"; interface Props extends ViewProps {}