This commit is contained in:
Fredrik Burmester
2025-07-15 11:23:35 +02:00
parent f3a9fc9d1c
commit 0d7edca1ad
236 changed files with 1432 additions and 3792 deletions

View File

@@ -1,8 +1,9 @@
const DropdownMenu = !Platform.isTV ? require("zeego/dropdown-menu") : null;
import { APP_LANGUAGES } from "@/i18n";
import { useSettings } from "@/utils/atoms/settings";
import { useTranslation } from "react-i18next";
import { Platform, TouchableOpacity, View, type ViewProps } from "react-native";
import { APP_LANGUAGES } from "@/i18n";
import { useSettings } from "@/utils/atoms/settings";
import { Text } from "../common/Text";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";

View File

@@ -1,9 +1,11 @@
import { Platform, TouchableOpacity, View, type ViewProps } from "react-native";
const DropdownMenu = !Platform.isTV ? require("zeego/dropdown-menu") : null;
import { useSettings } from "@/utils/atoms/settings";
import { Ionicons } from "@expo/vector-icons";
import { useTranslation } from "react-i18next";
import { Switch } from "react-native-gesture-handler";
import { useSettings } from "@/utils/atoms/settings";
import { Text } from "../common/Text";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";

View File

@@ -1,5 +1,5 @@
import { useSettings } from "@/utils/atoms/settings";
import { Switch, View } from "react-native";
import { useSettings } from "@/utils/atoms/settings";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";

View File

@@ -1,14 +1,13 @@
import { useSessions, type useSessionsProps } from "@/hooks/useSessions";
import { useSettings } from "@/utils/atoms/settings";
import { useRouter } from "expo-router";
import React from "react";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { useSessions, type useSessionsProps } from "@/hooks/useSessions";
import { useSettings } from "@/utils/atoms/settings";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";
export const Dashboard = () => {
const [settings, updateSettings] = useSettings();
const [settings, _updateSettings] = useSettings();
const { sessions = [], isLoading } = useSessions({} as useSessionsProps);
const router = useRouter();

View File

@@ -1,5 +1,5 @@
import { Text } from "@/components/common/Text";
import { View, type ViewProps } from "react-native";
import { Text } from "@/components/common/Text";
const DisabledSetting: React.FC<
{ disabled: boolean; showText?: boolean; text?: string } & ViewProps

View File

@@ -1,3 +1,8 @@
import { Ionicons } from "@expo/vector-icons";
import { useQueryClient } from "@tanstack/react-query";
import { useRouter } from "expo-router";
import { useMemo } from "react";
import { Platform, Switch, TouchableOpacity } from "react-native";
import { Stepper } from "@/components/inputs/Stepper";
import { useDownload } from "@/providers/DownloadProvider";
import {
@@ -5,14 +10,11 @@ import {
type Settings,
useSettings,
} from "@/utils/atoms/settings";
import { Ionicons } from "@expo/vector-icons";
import { useQueryClient } from "@tanstack/react-query";
import { useRouter } from "expo-router";
import React, { useMemo } from "react";
import { Platform, Switch, TouchableOpacity } from "react-native";
const DropdownMenu = !Platform.isTV ? require("zeego/dropdown-menu") : null;
import DisabledSetting from "@/components/settings/DisabledSetting";
import { useTranslation } from "react-i18next";
import DisabledSetting from "@/components/settings/DisabledSetting";
import { Text } from "../common/Text";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";

View File

@@ -1,5 +0,0 @@
import React from "react";
export default function DownloadSettings({ ...props }) {
return <></>;
}

View File

@@ -1,15 +1,3 @@
import { Button } from "@/components/Button";
import { Loader } from "@/components/Loader";
import { Text } from "@/components/common/Text";
import { LargeMovieCarousel } from "@/components/home/LargeMovieCarousel";
import { ScrollingCollectionList } from "@/components/home/ScrollingCollectionList";
import { MediaListSection } from "@/components/medialists/MediaListSection";
import { Colors } from "@/constants/Colors";
import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache";
import { useDownload } from "@/providers/DownloadProvider";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { useSettings } from "@/utils/atoms/settings";
import { eventBus } from "@/utils/eventBus";
import { Feather, Ionicons } from "@expo/vector-icons";
import type { Api } from "@jellyfin/sdk";
import type {
@@ -25,24 +13,30 @@ import {
} from "@jellyfin/sdk/lib/utils/api";
import NetInfo from "@react-native-community/netinfo";
import { type QueryFunction, useQuery } from "@tanstack/react-query";
import {
useNavigation,
usePathname,
useRouter,
useSegments,
} from "expo-router";
import { useNavigation, useRouter, useSegments } from "expo-router";
import { useAtomValue } from "jotai";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import {
ActivityIndicator,
Platform,
RefreshControl,
ScrollView,
TouchableOpacity,
View,
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Button } from "@/components/Button";
import { Text } from "@/components/common/Text";
import { LargeMovieCarousel } from "@/components/home/LargeMovieCarousel";
import { ScrollingCollectionList } from "@/components/home/ScrollingCollectionList";
import { Loader } from "@/components/Loader";
import { MediaListSection } from "@/components/medialists/MediaListSection";
import { Colors } from "@/constants/Colors";
import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache";
import { useDownload } from "@/providers/DownloadProvider";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { useSettings } from "@/utils/atoms/settings";
import { eventBus } from "@/utils/eventBus";
type ScrollingCollectionListSection = {
type: "ScrollingCollectionList";
@@ -71,9 +65,9 @@ export const HomeIndex = () => {
const [loading, setLoading] = useState(false);
const [
settings,
updateSettings,
pluginSettings,
setPluginSettings,
_updateSettings,
_pluginSettings,
_setPluginSettings,
refreshStreamyfinPluginSettings,
] = useSettings();
@@ -88,12 +82,6 @@ export const HomeIndex = () => {
const { downloadedFiles, cleanCacheDirectory } = useDownload();
useEffect(() => {
if (Platform.isTV) {
navigation.setOptions({
headerLeft: () => null,
});
return;
}
const hasDownloads = downloadedFiles && downloadedFiles.length > 0;
navigation.setOptions({
headerLeft: () => (
@@ -114,7 +102,7 @@ export const HomeIndex = () => {
}, [downloadedFiles, navigation, router]);
useEffect(() => {
cleanCacheDirectory().catch((e) =>
cleanCacheDirectory().catch((_e) =>
console.error("Something went wrong cleaning cache directory"),
);
}, []);

View File

@@ -1,12 +1,12 @@
import { JellyseerrApi, useJellyseerr } from "@/hooks/useJellyseerr";
import { userAtom } from "@/providers/JellyfinProvider";
import { useSettings } from "@/utils/atoms/settings";
import { useMutation } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { toast } from "sonner-native";
import { JellyseerrApi, useJellyseerr } from "@/hooks/useJellyseerr";
import { userAtom } from "@/providers/JellyfinProvider";
import { useSettings } from "@/utils/atoms/settings";
import { Button } from "../Button";
import { Input } from "../common/Input";
import { Text } from "../common/Text";
@@ -24,7 +24,7 @@ export const JellyseerrSettings = () => {
const { t } = useTranslation();
const [user] = useAtom(userAtom);
const [settings, updateSettings, pluginSettings] = useSettings();
const [settings, updateSettings, _pluginSettings] = useSettings();
const [jellyseerrPassword, setJellyseerrPassword] = useState<
string | undefined

View File

@@ -1,5 +1,3 @@
import { apiAtom } from "@/providers/JellyfinProvider";
import { type Settings, useSettings } from "@/utils/atoms/settings";
import type {
CultureDto,
UserConfiguration,
@@ -8,13 +6,9 @@ import type {
import { getLocalizationApi, getUserApi } from "@jellyfin/sdk/lib/utils/api";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useAtomValue } from "jotai";
import React, {
createContext,
useContext,
type ReactNode,
useEffect,
useState,
} from "react";
import { createContext, type ReactNode, useContext, useEffect } from "react";
import { apiAtom } from "@/providers/JellyfinProvider";
import { type Settings, useSettings } from "@/utils/atoms/settings";
interface MediaContextType {
settings: Settings | null;
@@ -51,7 +45,7 @@ export const MediaProvider = ({ children }: { children: ReactNode }) => {
},
});
queryClient.invalidateQueries({ queryKey: ["authUser"] });
} catch (error) {}
} catch (_error) {}
}
};

View File

@@ -1,10 +1,10 @@
import { Stepper } from "@/components/inputs/Stepper";
import DisabledSetting from "@/components/settings/DisabledSetting";
import { useSettings } from "@/utils/atoms/settings";
import type React from "react";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import type { ViewProps } from "react-native";
import { Stepper } from "@/components/inputs/Stepper";
import DisabledSetting from "@/components/settings/DisabledSetting";
import { useSettings } from "@/utils/atoms/settings";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";

View File

@@ -1,3 +1,11 @@
import { Ionicons } from "@expo/vector-icons";
import { useRouter } from "expo-router";
import { TFunction } from "i18next";
import type React from "react";
import { useEffect, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Linking, Switch, TouchableOpacity } from "react-native";
import { toast } from "sonner-native";
import { BITRATES } from "@/components/BitrateSelector";
import Dropdown from "@/components/common/Dropdown";
import DisabledSetting from "@/components/settings/DisabledSetting";
@@ -8,21 +16,12 @@ import {
registerBackgroundFetchAsync,
unregisterBackgroundFetchAsync,
} from "@/utils/background-tasks";
import { Ionicons } from "@expo/vector-icons";
import { useRouter } from "expo-router";
import i18n, { TFunction } from "i18next";
import type React from "react";
import { useEffect, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Linking, Platform, Switch, TouchableOpacity } from "react-native";
import { toast } from "sonner-native";
import { Text } from "../common/Text";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";
const BackgroundFetch = !Platform.isTV
? require("expo-background-fetch")
: null;
const TaskManager = !Platform.isTV ? require("expo-task-manager") : null;
const BackgroundFetch = require("expo-background-fetch");
const TaskManager = require("expo-task-manager");
export const OtherSettings: React.FC = () => {
const router = useRouter();
@@ -34,8 +33,6 @@ export const OtherSettings: React.FC = () => {
* Background task
*******************/
const checkStatusAsync = async () => {
if (Platform.isTV) return;
await BackgroundFetch.getStatusAsync();
return await TaskManager.isTaskRegisteredAsync(BACKGROUND_FETCH_TASK);
};

View File

@@ -1,13 +1,12 @@
import { useSettings } from "@/utils/atoms/settings";
import { useRouter } from "expo-router";
import React from "react";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { useSettings } from "@/utils/atoms/settings";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";
export const PluginSettings = () => {
const [settings, updateSettings] = useSettings();
const [settings, _updateSettings] = useSettings();
const router = useRouter();

View File

@@ -1,5 +1,3 @@
import { useHaptic } from "@/hooks/useHaptic";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import {
BottomSheetBackdrop,
type BottomSheetBackdropProps,
@@ -13,6 +11,8 @@ import type React from "react";
import { useCallback, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Alert, View, type ViewProps } from "react-native";
import { useHaptic } from "@/hooks/useHaptic";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { Button } from "../Button";
import { Text } from "../common/Text";
import { ListGroup } from "../list/ListGroup";
@@ -63,7 +63,7 @@ export const QuickConnect: React.FC<Props> = ({ ...props }) => {
t("home.settings.quick_connect.invalid_code"),
);
}
} catch (e) {
} catch (_e) {
errorHapticFeedback();
Alert.alert(
t("home.settings.quick_connect.error"),

View File

@@ -1,12 +1,12 @@
import { Text } from "@/components/common/Text";
import { Colors } from "@/constants/Colors";
import { useHaptic } from "@/hooks/useHaptic";
import { useDownload } from "@/providers/DownloadProvider";
import { useQuery } from "@tanstack/react-query";
import * as FileSystem from "expo-file-system";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { toast } from "sonner-native";
import { Text } from "@/components/common/Text";
import { Colors } from "@/constants/Colors";
import { useHaptic } from "@/hooks/useHaptic";
import { useDownload } from "@/providers/DownloadProvider";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";
@@ -32,7 +32,7 @@ export const StorageSettings = () => {
try {
await deleteAllFiles();
successHapticFeedback();
} catch (e) {
} catch (_e) {
errorHapticFeedback();
toast.error(t("home.settings.toasts.error_deleting_files"));
}

View File

@@ -1,12 +1,14 @@
import { Platform, TouchableOpacity, View, type ViewProps } from "react-native";
const DropdownMenu = !Platform.isTV ? require("zeego/dropdown-menu") : null;
import Dropdown from "@/components/common/Dropdown";
import { Stepper } from "@/components/inputs/Stepper";
import { useSettings } from "@/utils/atoms/settings";
const _DropdownMenu = !Platform.isTV ? require("zeego/dropdown-menu") : null;
import { Ionicons } from "@expo/vector-icons";
import { SubtitlePlaybackMode } from "@jellyfin/sdk/lib/generated-client";
import { useTranslation } from "react-i18next";
import { Switch } from "react-native-gesture-handler";
import Dropdown from "@/components/common/Dropdown";
import { Stepper } from "@/components/inputs/Stepper";
import { useSettings } from "@/utils/atoms/settings";
import { Text } from "../common/Text";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";

View File

@@ -1,11 +1,8 @@
import { apiAtom, useJellyfin, userAtom } from "@/providers/JellyfinProvider";
import * as Application from "expo-application";
import Constants from "expo-constants";
import { useAtom } from "jotai";
import { useTranslation } from "react-i18next";
import { View, type ViewProps } from "react-native";
import { Button } from "../Button";
import { Text } from "../common/Text";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { ListGroup } from "../list/ListGroup";
import { ListItem } from "../list/ListItem";