fix: refactor

This commit is contained in:
Fredrik Burmester
2024-08-15 16:46:50 +02:00
parent 92a260b6f5
commit aa0fbd6fad
5 changed files with 229 additions and 140 deletions

View File

@@ -11,6 +11,7 @@ import Animated, {
useSharedValue,
withTiming,
} from "react-native-reanimated";
import { Text } from "./Text";
interface HorizontalScrollProps<T> extends ScrollViewProps {
data?: T[] | null;
@@ -19,18 +20,33 @@ interface HorizontalScrollProps<T> extends ScrollViewProps {
contentContainerStyle?: ViewStyle;
loadingContainerStyle?: ViewStyle;
height?: number;
loading?: boolean;
}
export function HorizontalScroll<T>({
data,
data = [],
renderItem,
containerStyle,
contentContainerStyle,
loadingContainerStyle,
loading = false,
height = 164,
...props
}: HorizontalScrollProps<T>): React.ReactElement {
if (!data) {
const animatedOpacity = useSharedValue(0);
const animatedStyle1 = useAnimatedStyle(() => {
return {
opacity: withTiming(animatedOpacity.value, { duration: 250 }),
};
});
useEffect(() => {
if (data) {
animatedOpacity.value = 1;
}
}, [data]);
if (data === undefined || data === null || loading) {
return (
<View
style={[
@@ -38,7 +54,6 @@ export function HorizontalScroll<T>({
flex: 1,
justifyContent: "center",
alignItems: "center",
height,
},
loadingContainerStyle,
]}
@@ -48,18 +63,6 @@ export function HorizontalScroll<T>({
);
}
const opacity = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => {
return {
opacity: withTiming(opacity.value, { duration: 250 }),
};
});
useEffect(() => {
if (data && data.length > 0) opacity.value = 1;
}, [data]);
return (
<ScrollView
horizontal
@@ -72,13 +75,18 @@ export function HorizontalScroll<T>({
className={`
flex flex-row px-4
`}
style={[animatedStyle]}
style={[animatedStyle1]}
>
{data?.map((item, index) => (
{data.map((item, index) => (
<View className="mr-2" key={index}>
<React.Fragment>{renderItem(item, index)}</React.Fragment>
</View>
))}
{data.length === 0 && (
<View className="flex-1 justify-center items-center">
<Text className="text-center text-gray-500">No data available</Text>
</View>
)}
</Animated.View>
</ScrollView>
);

View File

@@ -1,3 +1,4 @@
import { useFocusEffect } from "expo-router";
import React, { useEffect } from "react";
import { TextInputProps, TextProps } from "react-native";
import { TextInput } from "react-native";
@@ -5,9 +6,11 @@ export function Input(props: TextInputProps) {
const { style, ...otherProps } = props;
const inputRef = React.useRef<TextInput>(null);
useEffect(() => {
inputRef.current?.focus();
}, []);
useFocusEffect(
React.useCallback(() => {
inputRef.current?.focus();
}, []),
);
return (
<TextInput
@@ -17,6 +20,7 @@ export function Input(props: TextInputProps) {
style={[{ color: "white" }, style]}
{...otherProps}
placeholderTextColor={"#9CA3AF"}
clearButtonMode="while-editing"
/>
);
}

View File

@@ -0,0 +1,64 @@
import { TouchableOpacity, View, ViewProps } from "react-native";
import { Text } from "@/components/common/Text";
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { router } from "expo-router";
import ContinueWatchingPoster from "../ContinueWatchingPoster";
import { ItemCardText } from "../ItemCardText";
import { HorizontalScroll } from "../common/HorrizontalScroll";
import MoviePoster from "../MoviePoster";
interface Props extends ViewProps {
title: string;
loading?: boolean;
orientation?: "horizontal" | "vertical";
data?: BaseItemDto[] | null;
height?: "small" | "large";
disabled?: boolean;
}
export const ScrollingCollectionList: React.FC<Props> = ({
title,
data,
orientation = "vertical",
height = "small",
loading = false,
disabled = false,
...props
}) => {
if (disabled) return null;
return (
<View {...props}>
<Text className="px-4 text-2xl font-bold mb-2">{title}</Text>
<HorizontalScroll<BaseItemDto>
data={data}
height={orientation === "vertical" ? 247 : 164}
loading={loading}
renderItem={(item, index) => (
<TouchableOpacity
key={index}
onPress={() => {
if (item.Type === "Series")
router.push(`/series/${item.Id}/page`);
else if (item.Type === "CollectionFolder")
router.push(`/collections/${item.Id}/page`);
else router.push(`/items/${item.Id}/page`);
}}
className={`flex flex-col
${orientation === "vertical" ? "w-32" : "w-48"}
`}
>
<View>
{orientation === "vertical" ? (
<MoviePoster item={item} />
) : (
<ContinueWatchingPoster item={item} />
)}
<ItemCardText item={item} />
</View>
</TouchableOpacity>
)}
/>
</View>
);
};

View File

@@ -1,4 +1,4 @@
import { Switch, View } from "react-native";
import { Linking, Switch, TouchableOpacity, View } from "react-native";
import { Text } from "../common/Text";
import { useAtom } from "jotai";
import { useSettings } from "@/utils/atoms/settings";
@@ -9,14 +9,26 @@ export const SettingToggles: React.FC = () => {
return (
<View className="flex flex-col rounded-xl mb-4 overflow-hidden border-neutral-800 divide-y-2 divide-solid divide-neutral-800 ">
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
<Text>Auto rotate</Text>
<View className="shrink">
<Text className="font-semibold">Auto rotate</Text>
<Text className="text-xs opacity-50">
Important on android since the video player orientation is locked to
the app orientation.
</Text>
</View>
<Switch
value={settings?.autoRotate}
onValueChange={(value) => updateSettings({ autoRotate: value })}
/>
</View>
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
<Text>Start videos in fullscreen</Text>
<View className="shrink">
<Text className="font-semibold">Start videos in fullscreen</Text>
<Text className="text-xs opacity-50">
Clicking a video will start it in fullscreen mode, instead of
inline.
</Text>
</View>
<Switch
value={settings?.openFullScreenVideoPlayerByDefault}
onValueChange={(value) =>
@@ -24,6 +36,25 @@ export const SettingToggles: React.FC = () => {
}
/>
</View>
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
<View className="flex flex-col">
<Text className="font-semibold">Use popular lists plugin</Text>
<Text className="text-xs opacity-50">Made by: lostb1t</Text>
<TouchableOpacity
onPress={() => {
Linking.openURL(
"https://github.com/lostb1t/jellyfin-plugin-media-lists",
);
}}
>
<Text className="text-xs text-purple-600">More info</Text>
</TouchableOpacity>
</View>
<Switch
value={settings?.usePopularPlugin}
onValueChange={(value) => updateSettings({ usePopularPlugin: value })}
/>
</View>
</View>
);
};