mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
chore
This commit is contained in:
@@ -2,19 +2,16 @@ import { Text } from "@/components/common/Text";
|
||||
import { ListGroup } from "@/components/list/ListGroup";
|
||||
import { ListItem } from "@/components/list/ListItem";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import DisabledSetting from "@/components/settings/DisabledSetting";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useNavigation } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { Linking, Switch, View } from "react-native";
|
||||
import {useMemo} from "react";
|
||||
import DisabledSetting from "@/components/settings/DisabledSetting";
|
||||
import { useMemo } from "react";
|
||||
import { Linking, Switch } from "react-native";
|
||||
|
||||
export default function page() {
|
||||
const navigation = useNavigation();
|
||||
|
||||
const [api] = useAtom(apiAtom);
|
||||
const [user] = useAtom(userAtom);
|
||||
|
||||
@@ -50,18 +47,17 @@ export default function page() {
|
||||
staleTime: 0,
|
||||
});
|
||||
|
||||
const disabled = useMemo(() => (
|
||||
pluginSettings?.usePopularPlugin?.locked === true &&
|
||||
pluginSettings?.mediaListCollectionIds?.locked === true
|
||||
), [pluginSettings]);
|
||||
const disabled = useMemo(
|
||||
() =>
|
||||
pluginSettings?.usePopularPlugin?.locked === true &&
|
||||
pluginSettings?.mediaListCollectionIds?.locked === true,
|
||||
[pluginSettings]
|
||||
);
|
||||
|
||||
if (!settings) return null;
|
||||
|
||||
return (
|
||||
<DisabledSetting
|
||||
disabled={disabled}
|
||||
className="px-4 pt-4"
|
||||
>
|
||||
<DisabledSetting disabled={disabled} className="px-4 pt-4">
|
||||
<ListGroup title={"Enable plugin"} className="">
|
||||
<ListItem
|
||||
title={"Enable Popular Lists"}
|
||||
@@ -76,7 +72,7 @@ export default function page() {
|
||||
disabled={pluginSettings?.usePopularPlugin?.locked}
|
||||
onValueChange={(usePopularPlugin) =>
|
||||
updateSettings({ usePopularPlugin })
|
||||
}
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
</ListGroup>
|
||||
@@ -103,11 +99,17 @@ export default function page() {
|
||||
<ListItem
|
||||
key={mlc.Id}
|
||||
title={mlc.Name}
|
||||
disabled={pluginSettings?.mediaListCollectionIds?.locked}
|
||||
disabled={
|
||||
pluginSettings?.mediaListCollectionIds?.locked
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
disabled={pluginSettings?.mediaListCollectionIds?.locked}
|
||||
value={settings.mediaListCollectionIds?.includes(mlc.Id!)}
|
||||
disabled={
|
||||
pluginSettings?.mediaListCollectionIds?.locked
|
||||
}
|
||||
value={settings.mediaListCollectionIds?.includes(
|
||||
mlc.Id!
|
||||
)}
|
||||
onValueChange={(value) => {
|
||||
if (!settings.mediaListCollectionIds) {
|
||||
updateSettings({
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { Link, Stack, usePathname } from "expo-router";
|
||||
import { Link, Stack } from "expo-router";
|
||||
import { StyleSheet } from "react-native";
|
||||
|
||||
import { ThemedText } from "@/components/ThemedText";
|
||||
import { ThemedView } from "@/components/ThemedView";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function NotFoundScreen() {
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack.Screen options={{ title: "Oops!" }} />
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { tc } from "@/utils/textTools";
|
||||
import {
|
||||
BaseItemDto,
|
||||
MediaSourceInfo,
|
||||
} from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useMemo } from "react";
|
||||
import { TouchableOpacity, View } from "react-native";
|
||||
import * as DropdownMenu from "zeego/dropdown-menu";
|
||||
import { Text } from "./common/Text";
|
||||
import { convertBitsToMegabitsOrGigabits } from "@/utils/bToMb";
|
||||
|
||||
interface Props extends React.ComponentProps<typeof View> {
|
||||
item: BaseItemDto;
|
||||
@@ -34,9 +32,9 @@ export const MediaSourceSelector: React.FC<Props> = ({
|
||||
if (!mediaSources.length) return "";
|
||||
|
||||
let commonPrefix = "";
|
||||
for (let i = 0; i < mediaSources[0].Name.length; i++) {
|
||||
const char = mediaSources[0].Name[i];
|
||||
if (mediaSources.every((source) => source.Name[i] === char)) {
|
||||
for (let i = 0; i < mediaSources[0].Name!.length; i++) {
|
||||
const char = mediaSources[0].Name![i];
|
||||
if (mediaSources.every((source) => source.Name![i] === char)) {
|
||||
commonPrefix += char;
|
||||
} else {
|
||||
commonPrefix = commonPrefix.slice(0, -1);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { FontAwesome, Ionicons } from "@expo/vector-icons";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { TouchableOpacity, View, ViewProps } from "react-native";
|
||||
import { FilterSheet } from "./FilterSheet";
|
||||
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
import React, {useCallback} from "react";
|
||||
import {
|
||||
useJellyseerr,
|
||||
} from "@/hooks/useJellyseerr";
|
||||
import {TouchableOpacity, ViewProps} from "react-native";
|
||||
import Slide, {SlideProps} from "@/components/jellyseerr/discover/Slide";
|
||||
import {COMPANY_LOGO_IMAGE_FILTER, Network} from "@/utils/jellyseerr/src/components/Discover/NetworkSlider";
|
||||
import GenericSlideCard from "@/components/jellyseerr/discover/GenericSlideCard";
|
||||
import {Studio} from "@/utils/jellyseerr/src/components/Discover/StudioSlider";
|
||||
import {router, useSegments} from "expo-router";
|
||||
import Slide, { SlideProps } from "@/components/jellyseerr/discover/Slide";
|
||||
import { useJellyseerr } from "@/hooks/useJellyseerr";
|
||||
import {
|
||||
COMPANY_LOGO_IMAGE_FILTER,
|
||||
Network,
|
||||
} from "@/utils/jellyseerr/src/components/Discover/NetworkSlider";
|
||||
import { Studio } from "@/utils/jellyseerr/src/components/Discover/StudioSlider";
|
||||
import { router, useSegments } from "expo-router";
|
||||
import React, { useCallback } from "react";
|
||||
import { TouchableOpacity, ViewProps } from "react-native";
|
||||
|
||||
const CompanySlide: React.FC<{data: Network[] | Studio[]} & SlideProps & ViewProps> = ({ slide, data, ...props }) => {
|
||||
const CompanySlide: React.FC<
|
||||
{ data: Network[] | Studio[] } & SlideProps & ViewProps
|
||||
> = ({ slide, data, ...props }) => {
|
||||
const segments = useSegments();
|
||||
const { jellyseerrApi } = useJellyseerr();
|
||||
const from = segments[2];
|
||||
|
||||
const navigate = useCallback(({id, image, name}: Network | Studio) => router.push({
|
||||
pathname: `/(auth)/(tabs)/${from}/jellyseerr/company/${id}`,
|
||||
params: {id, image, name, type: slide.type }
|
||||
}), [slide]);
|
||||
const navigate = useCallback(
|
||||
({ id, image, name }: Network | Studio) =>
|
||||
router.push({
|
||||
pathname: `/(auth)/(tabs)/${from}/jellyseerr/company/${id}`,
|
||||
params: { id, image, name, type: slide.type },
|
||||
}),
|
||||
[slide]
|
||||
);
|
||||
|
||||
return (
|
||||
<Slide
|
||||
@@ -30,7 +37,10 @@ const CompanySlide: React.FC<{data: Network[] | Studio[]} & SlideProps & ViewPro
|
||||
<GenericSlideCard
|
||||
className="w-28 rounded-lg overflow-hidden border border-neutral-900 p-4"
|
||||
id={item.id.toString()}
|
||||
url={jellyseerrApi?.imageProxy(item.image, COMPANY_LOGO_IMAGE_FILTER)}
|
||||
url={jellyseerrApi?.imageProxy(
|
||||
item.image,
|
||||
COMPANY_LOGO_IMAGE_FILTER
|
||||
)}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
||||
@@ -1,55 +1,66 @@
|
||||
import React, {useCallback} from "react";
|
||||
import {Endpoints, useJellyseerr,} from "@/hooks/useJellyseerr";
|
||||
import {TouchableOpacity, ViewProps} from "react-native";
|
||||
import Slide, {SlideProps} from "@/components/jellyseerr/discover/Slide";
|
||||
import GenericSlideCard from "@/components/jellyseerr/discover/GenericSlideCard";
|
||||
import {router, useSegments} from "expo-router";
|
||||
import {useQuery} from "@tanstack/react-query";
|
||||
import {DiscoverSliderType} from "@/utils/jellyseerr/server/constants/discover";
|
||||
import {genreColorMap} from "@/utils/jellyseerr/src/components/Discover/constants";
|
||||
import {GenreSliderItem} from "@/utils/jellyseerr/server/interfaces/api/discoverInterfaces";
|
||||
import Slide, { SlideProps } from "@/components/jellyseerr/discover/Slide";
|
||||
import { Endpoints, useJellyseerr } from "@/hooks/useJellyseerr";
|
||||
import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover";
|
||||
import { GenreSliderItem } from "@/utils/jellyseerr/server/interfaces/api/discoverInterfaces";
|
||||
import { genreColorMap } from "@/utils/jellyseerr/src/components/Discover/constants";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { router, useSegments } from "expo-router";
|
||||
import React, { useCallback } from "react";
|
||||
import { TouchableOpacity, ViewProps } from "react-native";
|
||||
|
||||
const GenreSlide: React.FC<SlideProps & ViewProps> = ({ slide, ...props }) => {
|
||||
const segments = useSegments();
|
||||
const { jellyseerrApi } = useJellyseerr();
|
||||
const from = segments[2];
|
||||
|
||||
const navigate = useCallback((genre: GenreSliderItem) => router.push({
|
||||
pathname: `/(auth)/(tabs)/${from}/jellyseerr/genre/${genre.id}`,
|
||||
params: {type: slide.type, name: genre.name}
|
||||
}), [slide]);
|
||||
const navigate = useCallback(
|
||||
(genre: GenreSliderItem) =>
|
||||
router.push({
|
||||
pathname: `/(auth)/(tabs)/${from}/jellyseerr/genre/${genre.id}`,
|
||||
params: { type: slide.type, name: genre.name },
|
||||
}),
|
||||
[slide]
|
||||
);
|
||||
|
||||
const {data, isFetching, isLoading } = useQuery({
|
||||
queryKey: ['jellyseerr', 'discover', slide.type, slide.id],
|
||||
const { data, isFetching, isLoading } = useQuery({
|
||||
queryKey: ["jellyseerr", "discover", slide.type, slide.id],
|
||||
queryFn: async () => {
|
||||
return jellyseerrApi?.getGenreSliders(
|
||||
slide.type == DiscoverSliderType.MOVIE_GENRES
|
||||
? Endpoints.MOVIE
|
||||
: Endpoints.TV
|
||||
)
|
||||
);
|
||||
},
|
||||
enabled: !!jellyseerrApi
|
||||
})
|
||||
enabled: !!jellyseerrApi,
|
||||
});
|
||||
|
||||
return (
|
||||
data && <Slide
|
||||
{...props}
|
||||
slide={slide}
|
||||
data={data}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
renderItem={(item, index) => (
|
||||
<TouchableOpacity className="mr-2" onPress={() => navigate(item)}>
|
||||
<GenericSlideCard
|
||||
className="w-28 rounded-lg overflow-hidden border border-neutral-900"
|
||||
id={item.id.toString()}
|
||||
title={item.name}
|
||||
colors={[]}
|
||||
contentFit={"cover"}
|
||||
url={jellyseerrApi?.imageProxy(item.backdrops?.[0], `w780_filter(duotone,${genreColorMap[item.id] ?? genreColorMap[0]})`)}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
/>
|
||||
data && (
|
||||
<Slide
|
||||
{...props}
|
||||
slide={slide}
|
||||
data={data}
|
||||
keyExtractor={(item) => item.id.toString()}
|
||||
renderItem={(item, index) => (
|
||||
<TouchableOpacity className="mr-2" onPress={() => navigate(item)}>
|
||||
<GenericSlideCard
|
||||
className="w-28 rounded-lg overflow-hidden border border-neutral-900"
|
||||
id={item.id.toString()}
|
||||
title={item.name}
|
||||
colors={[]}
|
||||
contentFit={"cover"}
|
||||
url={jellyseerrApi?.imageProxy(
|
||||
item.backdrops?.[0],
|
||||
`w780_filter(duotone,${
|
||||
genreColorMap[item.id] ?? genreColorMap[0]
|
||||
})`
|
||||
)}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { PropsWithChildren, ReactNode } from "react";
|
||||
import {
|
||||
TouchableOpacity,
|
||||
@@ -6,7 +7,6 @@ import {
|
||||
ViewProps,
|
||||
} from "react-native";
|
||||
import { Text } from "../common/Text";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
|
||||
interface Props extends TouchableOpacityProps, ViewProps {
|
||||
title?: string | null | undefined;
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { Button } from "@/components/Button";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { useHaptic } from "@/hooks/useHaptic";
|
||||
import { useDownload } from "@/providers/DownloadProvider";
|
||||
import { clearLogs } from "@/utils/log";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import * as FileSystem from "expo-file-system";
|
||||
import { useHaptic } from "@/hooks/useHaptic";
|
||||
import { View } from "react-native";
|
||||
import * as Progress from "react-native-progress";
|
||||
import { toast } from "sonner-native";
|
||||
import { ListGroup } from "../list/ListGroup";
|
||||
import { ListItem } from "../list/ListItem";
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { runtimeTicksToSeconds } from "@/utils/time";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { atom, useAtom } from "jotai";
|
||||
import { useEffect, useMemo, useState, useRef } from "react";
|
||||
import { View, TouchableOpacity } from "react-native";
|
||||
import { getTvShowsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { getUserItemData } from "@/utils/jellyfin/user-library/getUserItemData";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import ContinueWatchingPoster from "@/components/ContinueWatchingPoster";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { DownloadSingleItem } from "@/components/DownloadItem";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import {
|
||||
HorizontalScroll,
|
||||
HorizontalScrollRef,
|
||||
} from "@/components/common/HorrizontalScroll";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import ContinueWatchingPoster from "@/components/ContinueWatchingPoster";
|
||||
import { DownloadSingleItem } from "@/components/DownloadItem";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import {
|
||||
SeasonDropdown,
|
||||
SeasonIndexState,
|
||||
} from "@/components/series/SeasonDropdown";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { getUserItemData } from "@/utils/jellyfin/user-library/getUserItemData";
|
||||
import { runtimeTicksToSeconds } from "@/utils/time";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getTvShowsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { atom, useAtom } from "jotai";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { TouchableOpacity, View } from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
|
||||
type Props = {
|
||||
item: BaseItemDto;
|
||||
|
||||
Reference in New Issue
Block a user