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,9 +1,9 @@
import { apiAtom } from "@/providers/JellyfinProvider";
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
import { getTvShowsApi } from "@jellyfin/sdk/lib/utils/api";
import { useQuery } from "@tanstack/react-query";
import { useAtomValue } from "jotai";
import { useMemo } from "react";
import { apiAtom } from "@/providers/JellyfinProvider";
interface AdjacentEpisodesProps {
item?: BaseItemDto | null;

View File

@@ -1,9 +1,5 @@
import { useCallback, useEffect, useRef, useState } from "react";
import {
runOnJS,
useAnimatedReaction,
useSharedValue,
} from "react-native-reanimated";
import { useCallback, useEffect, useRef } from "react";
import { useSharedValue } from "react-native-reanimated";
export const useControlsVisibility = (timeout = 3000) => {
const opacity = useSharedValue(1);

View File

@@ -1,10 +1,10 @@
import { useQuery } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { useCallback, useEffect, useState } from "react";
import { apiAtom } from "@/providers/JellyfinProvider";
import { getAuthHeaders } from "@/utils/jellyfin/jellyfin";
import { writeToLog } from "@/utils/log";
import { msToSeconds, secondsToMs } from "@/utils/time";
import { useQuery } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { useCallback, useEffect, useState } from "react";
import { useHaptic } from "./useHaptic";
interface CreditTimestamps {

View File

@@ -1,9 +1,9 @@
import { usePlaySettings } from "@/providers/PlaySettingsProvider";
import { writeToLog } from "@/utils/log";
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
import * as FileSystem from "expo-file-system";
import { useRouter } from "expo-router";
import { useCallback } from "react";
import { usePlaySettings } from "@/providers/PlaySettingsProvider";
import { writeToLog } from "@/utils/log";
export const getDownloadedFileUrl = async (itemId: string): Promise<string> => {
const directory = FileSystem.documentDirectory;

View File

@@ -1,9 +1,9 @@
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
import { getUserLibraryApi } from "@jellyfin/sdk/lib/utils/api";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { useEffect, useMemo, useState } from "react";
import { useEffect, useState } from "react";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
export const useFavorite = (item: BaseItemDto) => {
const queryClient = useQueryClient();
@@ -49,7 +49,7 @@ export const useFavorite = (item: BaseItemDto) => {
return { previousItem };
},
onError: (err, variables, context) => {
onError: (_err, _variables, context) => {
if (context?.previousItem) {
queryClient.setQueryData([type, item.Id], context.previousItem);
}
@@ -80,7 +80,7 @@ export const useFavorite = (item: BaseItemDto) => {
return { previousItem };
},
onError: (err, variables, context) => {
onError: (_err, _variables, context) => {
if (context?.previousItem) {
queryClient.setQueryData([type, item.Id], context.previousItem);
}

View File

@@ -1,7 +1,8 @@
import { useSettings } from "@/utils/atoms/settings";
import { useCallback, useMemo } from "react";
import { Platform } from "react-native";
const Haptics = !Platform.isTV ? require("expo-haptics") : null;
import { useSettings } from "@/utils/atoms/settings";
const Haptics = require("expo-haptics");
export type HapticFeedbackType =
| "light"
@@ -15,21 +16,15 @@ export type HapticFeedbackType =
export const useHaptic = (feedbackType: HapticFeedbackType = "selection") => {
const [settings] = useSettings();
if (Platform.isTV) {
return () => {};
}
const createHapticHandler = useCallback(
(type: typeof Haptics.ImpactFeedbackStyle) => {
return Platform.OS === "web" || Platform.isTV
? () => {}
: () => Haptics.impactAsync(type);
return Platform.OS === "web" ? () => {} : () => Haptics.impactAsync(type);
},
[],
);
const createNotificationFeedback = useCallback(
(type: typeof Haptics.NotificationFeedbackType) => {
return Platform.OS === "web" || Platform.isTV
return Platform.OS === "web"
? () => {}
: () => Haptics.notificationAsync(type);
},
@@ -41,10 +36,7 @@ export const useHaptic = (feedbackType: HapticFeedbackType = "selection") => {
light: createHapticHandler(Haptics.ImpactFeedbackStyle.Light),
medium: createHapticHandler(Haptics.ImpactFeedbackStyle.Medium),
heavy: createHapticHandler(Haptics.ImpactFeedbackStyle.Heavy),
selection:
Platform.OS === "web" || Platform.isTV
? () => {}
: Haptics.selectionAsync,
selection: Platform.OS === "web" ? () => {} : Haptics.selectionAsync,
success: createNotificationFeedback(
Haptics.NotificationFeedbackType.Success,
),

View File

@@ -1,3 +1,6 @@
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
import { useAtom, useAtomValue } from "jotai";
import { useEffect, useMemo } from "react";
import { apiAtom } from "@/providers/JellyfinProvider";
import {
adjustToNearBlack,
@@ -7,12 +10,9 @@ import {
} from "@/utils/atoms/primaryColor";
import { getItemImage } from "@/utils/getItemImage";
import { storage } from "@/utils/mmkv";
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
import { useAtom, useAtomValue } from "jotai";
import { useEffect, useMemo } from "react";
import { Platform } from "react-native";
// import { getColors } from "react-native-image-colors";
const Colors = !Platform.isTV ? require("react-native-image-colors") : null;
const Colors = require("react-native-image-colors");
/**
* Custom hook to extract and manage image colors for a given item.
@@ -30,8 +30,6 @@ export const useImageColors = ({
url?: string | null;
disabled?: boolean;
}) => {
if (Platform.isTV) return;
const api = useAtomValue(apiAtom);
const [, setPrimaryColor] = useAtom(itemThemeColorAtom);

View File

@@ -1,5 +1,5 @@
import { storage } from "@/utils/mmkv";
import { useCallback } from "react";
import { storage } from "@/utils/mmkv";
const useImageStorage = () => {
const saveBase64Image = useCallback(async (base64: string, key: string) => {

View File

@@ -1,10 +1,10 @@
import { useQuery } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { useCallback, useEffect, useState } from "react";
import { apiAtom } from "@/providers/JellyfinProvider";
import { getAuthHeaders } from "@/utils/jellyfin/jellyfin";
import { writeToLog } from "@/utils/log";
import { msToSeconds, secondsToMs } from "@/utils/time";
import { useQuery } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { useCallback, useEffect, useState } from "react";
import { useHaptic } from "./useHaptic";
interface IntroTimestamps {

View File

@@ -1,3 +1,7 @@
import axios, { type AxiosError, type AxiosInstance } from "axios";
import { atom } from "jotai";
import { useAtom } from "jotai/index";
import { inRange } from "lodash";
import type { User as JellyseerrUser } from "@/utils/jellyseerr/server/entity/User";
import type {
MovieResult,
@@ -5,11 +9,11 @@ import type {
TvResult,
} from "@/utils/jellyseerr/server/models/Search";
import { storage } from "@/utils/mmkv";
import axios, { type AxiosError, type AxiosInstance } from "axios";
import { atom } from "jotai";
import { useAtom } from "jotai/index";
import { inRange } from "lodash";
import "@/augmentations";
import { useQueryClient } from "@tanstack/react-query";
import { t } from "i18next";
import { useCallback, useMemo } from "react";
import { toast } from "sonner-native";
import { useSettings } from "@/utils/atoms/settings";
import type { RTRating } from "@/utils/jellyseerr/server/api/rating/rottentomatoes";
import {
@@ -43,10 +47,6 @@ import type {
TvDetails,
} from "@/utils/jellyseerr/server/models/Tv";
import { writeErrorLog } from "@/utils/log";
import { useQueryClient } from "@tanstack/react-query";
import { t } from "i18next";
import { useCallback, useMemo } from "react";
import { toast } from "sonner-native";
interface SearchParams {
query: string;

View File

@@ -1,9 +1,9 @@
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { markAsNotPlayed } from "@/utils/jellyfin/playstate/markAsNotPlayed";
import { markAsPlayed } from "@/utils/jellyfin/playstate/markAsPlayed";
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { useQueryClient } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { markAsNotPlayed } from "@/utils/jellyfin/playstate/markAsNotPlayed";
import { markAsPlayed } from "@/utils/jellyfin/playstate/markAsPlayed";
import { useHaptic } from "./useHaptic";
export const useMarkAsPlayed = (items: BaseItemDto[]) => {

View File

@@ -1,17 +1,12 @@
import { useEffect, useState } from "react";
import * as ScreenOrientation from "@/packages/expo-screen-orientation";
import orientationToOrientationLock from "@/utils/OrientationLockConverter";
import { useEffect, useState } from "react";
import { Platform } from "react-native";
export const useOrientation = () => {
const [orientation, setOrientation] = useState(
Platform.isTV
? ScreenOrientation.OrientationLock.LANDSCAPE
: ScreenOrientation.OrientationLock.UNKNOWN,
ScreenOrientation.OrientationLock.UNKNOWN,
);
if (Platform.isTV) return { orientation, setOrientation };
useEffect(() => {
const orientationSubscription =
ScreenOrientation.addOrientationChangeListener((event) => {

View File

@@ -1,10 +1,9 @@
import { apiAtom } from "@/providers/JellyfinProvider";
import { userAtom } from "@/providers/JellyfinProvider";
import { getSessionApi } from "@jellyfin/sdk/lib/utils/api/session-api";
import { useQuery } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { Platform } from "react-native";
const Notifications = !Platform.isTV ? require("expo-notifications") : null;
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
const _Notifications = require("expo-notifications");
export interface useSessionsProps {
refetchInterval: number;

View File

@@ -1,9 +1,9 @@
import { apiAtom } from "@/providers/JellyfinProvider";
import { ticksToMs } from "@/utils/time";
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
import { Image } from "expo-image";
import { useAtom } from "jotai";
import { useCallback, useMemo, useRef, useState } from "react";
import { apiAtom } from "@/providers/JellyfinProvider";
import { ticksToMs } from "@/utils/time";
interface TrickplayData {
Interval?: number;

View File

@@ -1,8 +1,8 @@
import { useWebSocketContext } from "@/providers/WebSocketProvider";
import { useRouter } from "expo-router";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { Alert } from "react-native";
import { useWebSocketContext } from "@/providers/WebSocketProvider";
interface UseWebSocketProps {
isPlaying: boolean;
@@ -88,7 +88,7 @@ export const useWebSocket = ({
if (!lastMessage) return;
if (offline) return;
const messageType = lastMessage.MessageType;
const _messageType = lastMessage.MessageType;
const command: string | undefined =
lastMessage?.Data?.Command || lastMessage?.Data?.Name;
@@ -252,7 +252,7 @@ export const useWebSocket = ({
});
if (itemIdsStr) {
const itemIds = itemIdsStr.split(",");
let startPositionTicks: number | undefined = undefined;
let startPositionTicks: number | undefined;
if (startPositionTicksStr) {
const parsedTicks = Number.parseInt(startPositionTicksStr, 10);
if (!Number.isNaN(parsedTicks)) {