forked from Ninjalama/streamyfin_mirror
wip
This commit is contained in:
@@ -5,6 +5,7 @@ import { useAtom } from "jotai";
|
||||
import { useMemo, useState } from "react";
|
||||
import { View } from "react-native";
|
||||
import { WatchedIndicator } from "./WatchedIndicator";
|
||||
import React from "react";
|
||||
|
||||
type ContinueWatchingPosterProps = {
|
||||
item: BaseItemDto;
|
||||
@@ -14,7 +15,6 @@ type ContinueWatchingPosterProps = {
|
||||
|
||||
const ContinueWatchingPoster: React.FC<ContinueWatchingPosterProps> = ({
|
||||
item,
|
||||
width = 176,
|
||||
useEpisodePoster = false,
|
||||
}) => {
|
||||
const [api] = useAtom(apiAtom);
|
||||
@@ -47,21 +47,11 @@ const ContinueWatchingPoster: React.FC<ContinueWatchingPosterProps> = ({
|
||||
|
||||
if (!url)
|
||||
return (
|
||||
<View
|
||||
className="aspect-video border border-neutral-800"
|
||||
style={{
|
||||
width,
|
||||
}}
|
||||
></View>
|
||||
<View className="aspect-video border border-neutral-800 w-44"></View>
|
||||
);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
width,
|
||||
}}
|
||||
className="relative aspect-video rounded-lg overflow-hidden border border-neutral-800"
|
||||
>
|
||||
<View className="relative w-44 aspect-video rounded-lg overflow-hidden border border-neutral-800">
|
||||
<Image
|
||||
key={item.Id}
|
||||
id={item.Id}
|
||||
|
||||
@@ -23,7 +23,11 @@ export const ListItem: React.FC<PropsWithChildren<Props>> = ({
|
||||
>
|
||||
<View className="flex flex-col">
|
||||
<Text className="font-bold ">{title}</Text>
|
||||
{subTitle && <Text className="text-xs">{subTitle}</Text>}
|
||||
{subTitle && (
|
||||
<Text className="text-xs" selectable>
|
||||
{subTitle}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
{iconAfter}
|
||||
</View>
|
||||
|
||||
@@ -21,11 +21,17 @@ export const PlayedStatus: React.FC<Props> = ({ item, ...props }) => {
|
||||
|
||||
const invalidateQueries = () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["item"],
|
||||
queryKey: ["item", item.Id],
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["resumeItems"],
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["continueWatching"],
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["nextUp-all"],
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["nextUp"],
|
||||
});
|
||||
|
||||
@@ -98,7 +98,6 @@ export const HorizontalScroll = forwardRef<
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,12 +6,13 @@ import {
|
||||
type QueryFunction,
|
||||
type QueryKey,
|
||||
} from "@tanstack/react-query";
|
||||
import { View, ViewProps } from "react-native";
|
||||
import { ScrollView, View, ViewProps } from "react-native";
|
||||
import ContinueWatchingPoster from "../ContinueWatchingPoster";
|
||||
import { ItemCardText } from "../ItemCardText";
|
||||
import { HorizontalScroll } from "../common/HorrizontalScroll";
|
||||
import { TouchableItemRouter } from "../common/TouchableItemRouter";
|
||||
import SeriesPoster from "../posters/SeriesPoster";
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
|
||||
interface Props extends ViewProps {
|
||||
title?: string | null;
|
||||
@@ -39,40 +40,56 @@ export const ScrollingCollectionList: React.FC<Props> = ({
|
||||
if (disabled || !title) return null;
|
||||
|
||||
return (
|
||||
<View {...props}>
|
||||
<View {...props} className="">
|
||||
<Text className="px-4 text-lg font-bold mb-2 text-neutral-100">
|
||||
{title}
|
||||
</Text>
|
||||
<HorizontalScroll
|
||||
data={data}
|
||||
extraData={[orientation, isLoading]}
|
||||
loading={isLoading}
|
||||
renderItem={(item, index) => (
|
||||
<TouchableItemRouter
|
||||
item={item}
|
||||
key={index}
|
||||
style={{
|
||||
width: orientation === "horizontal" ? 176 : 112,
|
||||
zIndex: 100,
|
||||
}}
|
||||
>
|
||||
{item.Type === "Episode" && orientation === "horizontal" && (
|
||||
<ContinueWatchingPoster item={item} />
|
||||
)}
|
||||
{item.Type === "Episode" && orientation === "vertical" && (
|
||||
<SeriesPoster item={item} />
|
||||
)}
|
||||
{item.Type === "Movie" && orientation === "horizontal" && (
|
||||
<ContinueWatchingPoster item={item} />
|
||||
)}
|
||||
{item.Type === "Movie" && orientation === "vertical" && (
|
||||
<MoviePoster item={item} />
|
||||
)}
|
||||
{item.Type === "Series" && <SeriesPoster item={item} />}
|
||||
<ItemCardText item={item} />
|
||||
</TouchableItemRouter>
|
||||
)}
|
||||
/>
|
||||
{isLoading ? (
|
||||
<View
|
||||
className={`
|
||||
flex flex-row gap-2 px-4
|
||||
`}
|
||||
>
|
||||
{[1, 2, 3].map((i) => (
|
||||
<View className="w-44 mb-2">
|
||||
<View className="bg-neutral-800 h-24 w-full rounded-md mb-2"></View>
|
||||
<View className="bg-neutral-800 h-4 w-full rounded-md mb-2"></View>
|
||||
<View className="bg-neutral-800 h-4 w-1/2 rounded-md"></View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
) : (
|
||||
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
||||
<View className="px-4 flex flex-row">
|
||||
{data?.map((item, index) => (
|
||||
<TouchableItemRouter
|
||||
item={item}
|
||||
key={index}
|
||||
className={`
|
||||
mr-2
|
||||
|
||||
${orientation === "horizontal" ? "w-44" : "w-28"}
|
||||
`}
|
||||
>
|
||||
{item.Type === "Episode" && orientation === "horizontal" && (
|
||||
<ContinueWatchingPoster item={item} />
|
||||
)}
|
||||
{item.Type === "Episode" && orientation === "vertical" && (
|
||||
<SeriesPoster item={item} />
|
||||
)}
|
||||
{item.Type === "Movie" && orientation === "horizontal" && (
|
||||
<ContinueWatchingPoster item={item} />
|
||||
)}
|
||||
{item.Type === "Movie" && orientation === "vertical" && (
|
||||
<MoviePoster item={item} />
|
||||
)}
|
||||
{item.Type === "Series" && <SeriesPoster item={item} />}
|
||||
<ItemCardText item={item} />
|
||||
</TouchableItemRouter>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ const MoviePoster: React.FC<MoviePosterProps> = ({
|
||||
}, [item]);
|
||||
|
||||
return (
|
||||
<View className="relative rounded-lg overflow-hidden border border-neutral-900">
|
||||
<View className="relative rounded-lg overflow-hidden border border-neutral-900 w-28 aspect-[10/15]">
|
||||
<Image
|
||||
placeholder={{
|
||||
blurhash,
|
||||
@@ -57,7 +57,6 @@ const MoviePoster: React.FC<MoviePosterProps> = ({
|
||||
width: "100%",
|
||||
}}
|
||||
/>
|
||||
|
||||
<WatchedIndicator item={item} />
|
||||
{showProgress && progress > 0 && (
|
||||
<View className="h-1 bg-red-600 w-full"></View>
|
||||
|
||||
@@ -32,7 +32,7 @@ const SeriesPoster: React.FC<MoviePosterProps> = ({ item }) => {
|
||||
}, [item]);
|
||||
|
||||
return (
|
||||
<View className="relative rounded-lg overflow-hidden border border-neutral-900">
|
||||
<View className="w-28 aspect-[10/15] relative rounded-lg overflow-hidden border border-neutral-900 ">
|
||||
<Image
|
||||
placeholder={{
|
||||
blurhash,
|
||||
@@ -49,7 +49,7 @@ const SeriesPoster: React.FC<MoviePosterProps> = ({ item }) => {
|
||||
cachePolicy={"memory-disk"}
|
||||
contentFit="cover"
|
||||
style={{
|
||||
aspectRatio: "10/15",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { useDownload } from "@/providers/DownloadProvider";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import {
|
||||
apiAtom,
|
||||
getOrSetDeviceId,
|
||||
userAtom,
|
||||
} from "@/providers/JellyfinProvider";
|
||||
import { ScreenOrientationEnum, useSettings } from "@/utils/atoms/settings";
|
||||
import {
|
||||
BACKGROUND_FETCH_TASK,
|
||||
@@ -28,6 +32,8 @@ 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 {}
|
||||
|
||||
@@ -44,6 +50,21 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { data: optimizeServerStatistics } = useQuery({
|
||||
queryKey: ["optimize-server", settings?.optimizedVersionsServerUrl],
|
||||
queryFn: async () =>
|
||||
getStatistics({
|
||||
url: settings?.optimizedVersionsServerUrl,
|
||||
authHeader: api?.accessToken,
|
||||
deviceId: await getOrSetDeviceId(),
|
||||
}),
|
||||
refetchInterval: 1000,
|
||||
staleTime: 0,
|
||||
enabled:
|
||||
!!settings?.optimizedVersionsServerUrl &&
|
||||
settings.optimizedVersionsServerUrl.length > 0,
|
||||
});
|
||||
|
||||
/********************
|
||||
* Background task
|
||||
*******************/
|
||||
@@ -568,11 +589,24 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
>
|
||||
<View className="flex flex-col bg-neutral-900 px-4 py-4">
|
||||
<View className="flex flex-col shrink mb-2">
|
||||
<Text className="font-semibold">Optimized versions server</Text>
|
||||
<View className="flex flex-row justify-between items-center">
|
||||
<Text className="font-semibold">
|
||||
Optimized versions server
|
||||
</Text>
|
||||
<View
|
||||
className={`
|
||||
w-3 h-3 rounded-full
|
||||
${
|
||||
optimizeServerStatistics ? "bg-green-600" : "bg-red-600"
|
||||
}
|
||||
`}
|
||||
></View>
|
||||
</View>
|
||||
<Text className="text-xs opacity-50">
|
||||
Set the URL for the optimized versions server for downloads.
|
||||
</Text>
|
||||
</View>
|
||||
<View></View>
|
||||
<View className="flex flex-col">
|
||||
<Input
|
||||
placeholder="Optimized versions server URL..."
|
||||
@@ -587,7 +621,7 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
color="purple"
|
||||
className="h-12 mt-2"
|
||||
onPress={() => {
|
||||
toast.success("Saved");
|
||||
toast.info("Saved");
|
||||
updateSettings({
|
||||
optimizedVersionsServerUrl:
|
||||
optimizedVersionsServerUrl.length === 0
|
||||
|
||||
Reference in New Issue
Block a user