mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 23:59:08 +00:00
fix: loading indicator style
This commit is contained in:
@@ -2,6 +2,7 @@ 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 { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
@@ -19,12 +20,7 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { useRouter } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
RefreshControl,
|
||||
ScrollView,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { RefreshControl, ScrollView, View } from "react-native";
|
||||
|
||||
export default function index() {
|
||||
const router = useRouter();
|
||||
@@ -250,10 +246,10 @@ export default function index() {
|
||||
</View>
|
||||
);
|
||||
|
||||
if (isLoading)
|
||||
if (true)
|
||||
return (
|
||||
<View className="justify-center items-center h-full">
|
||||
<ActivityIndicator />
|
||||
<Loader />
|
||||
</View>
|
||||
);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { TouchableItemRouter } from "@/components/common/TouchableItemRouter";
|
||||
import { FilterButton } from "@/components/filters/FilterButton";
|
||||
import { ResetFiltersButton } from "@/components/filters/ResetFiltersButton";
|
||||
import { ItemCardText } from "@/components/ItemCardText";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import MoviePoster from "@/components/posters/MoviePoster";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import {
|
||||
@@ -24,7 +25,7 @@ import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
import { ActivityIndicator, ScrollView, View } from "react-native";
|
||||
import { ScrollView, View } from "react-native";
|
||||
|
||||
const page: React.FC = () => {
|
||||
const searchParams = useLocalSearchParams();
|
||||
@@ -284,12 +285,10 @@ const page: React.FC = () => {
|
||||
</View>
|
||||
</ScrollView>
|
||||
{!type && isFetching && (
|
||||
<ActivityIndicator
|
||||
<Loader
|
||||
style={{
|
||||
marginTop: 300,
|
||||
}}
|
||||
size={"small"}
|
||||
color={"white"}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
|
||||
@@ -1,35 +1,21 @@
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { getItemsApi, getUserViewsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { getPrimaryImageUrl } from "@/utils/jellyfin/image/getPrimaryImageUrl";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getUserViewsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Image } from "expo-image";
|
||||
import { useRouter } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
RefreshControl,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getPrimaryImageUrl } from "@/utils/jellyfin/image/getPrimaryImageUrl";
|
||||
import { Image } from "expo-image";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { useMemo } from "react";
|
||||
import { TouchableOpacity, View } from "react-native";
|
||||
|
||||
export default function index() {
|
||||
const router = useRouter();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const [api] = useAtom(apiAtom);
|
||||
const [user] = useAtom(userAtom);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [settings, _] = useSettings();
|
||||
|
||||
const { data, isLoading: isLoading } = useQuery({
|
||||
queryKey: ["user-views", user?.Id],
|
||||
queryFn: async () => {
|
||||
@@ -50,7 +36,7 @@ export default function index() {
|
||||
if (isLoading)
|
||||
return (
|
||||
<View className="justify-center items-center h-full">
|
||||
<ActivityIndicator />
|
||||
<Loader />
|
||||
</View>
|
||||
);
|
||||
|
||||
|
||||
@@ -4,28 +4,19 @@ import { Text } from "@/components/common/Text";
|
||||
import { TouchableItemRouter } from "@/components/common/TouchableItemRouter";
|
||||
import ContinueWatchingPoster from "@/components/ContinueWatchingPoster";
|
||||
import { ItemCardText } from "@/components/ItemCardText";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import AlbumCover from "@/components/posters/AlbumCover";
|
||||
import MoviePoster from "@/components/posters/MoviePoster";
|
||||
import Poster from "@/components/posters/Poster";
|
||||
import SeriesPoster from "@/components/posters/SeriesPoster";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { getPrimaryImageUrl } from "@/utils/jellyfin/image/getPrimaryImageUrl";
|
||||
import { getUserItemData } from "@/utils/jellyfin/user-library/getUserItemData";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getSearchApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { router, Stack, useNavigation } from "expo-router";
|
||||
import { router, useNavigation } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import React, { useLayoutEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Platform,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import _ from "lodash";
|
||||
import { Platform, ScrollView, TouchableOpacity, View } from "react-native";
|
||||
import { useDebounce } from "use-debounce";
|
||||
|
||||
const exampleSearches = [
|
||||
@@ -308,7 +299,7 @@ export default function search() {
|
||||
/>
|
||||
{loading ? (
|
||||
<View className="mt-4 flex justify-center items-center">
|
||||
<ActivityIndicator size="small" color="white" />
|
||||
<Loader />
|
||||
</View>
|
||||
) : noResults && debouncedSearch.length > 0 ? (
|
||||
<View>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import ArtistPoster from "@/components/posters/ArtistPoster";
|
||||
import MoviePoster from "@/components/posters/MoviePoster";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
@@ -13,12 +14,7 @@ import { useQuery } from "@tanstack/react-query";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { useMemo, useState } from "react";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { ScrollView, TouchableOpacity, View } from "react-native";
|
||||
|
||||
const page: React.FC = () => {
|
||||
const searchParams = useLocalSearchParams();
|
||||
@@ -154,7 +150,7 @@ const page: React.FC = () => {
|
||||
</View>
|
||||
{isLoading ? (
|
||||
<View className="my-12">
|
||||
<ActivityIndicator color={"white"} />
|
||||
<Loader />
|
||||
</View>
|
||||
) : (
|
||||
<View className="flex flex-row flex-wrap">
|
||||
|
||||
@@ -1,23 +1,18 @@
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { MovieCard } from "@/components/downloads/MovieCard";
|
||||
import { SeriesCard } from "@/components/downloads/SeriesCard";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import { runningProcesses } from "@/utils/atoms/downloads";
|
||||
import { queueAtom } from "@/utils/atoms/queue";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { useAtom } from "jotai";
|
||||
import { runningProcesses } from "@/utils/atoms/downloads";
|
||||
import { router } from "expo-router";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { FFmpegKit } from "ffmpeg-kit-react-native";
|
||||
import * as FileSystem from "expo-file-system";
|
||||
import { queueAtom } from "@/utils/atoms/queue";
|
||||
import { useAtom } from "jotai";
|
||||
import { useMemo } from "react";
|
||||
import { ScrollView, TouchableOpacity, View } from "react-native";
|
||||
|
||||
const downloads: React.FC = () => {
|
||||
const [process, setProcess] = useAtom(runningProcesses);
|
||||
@@ -27,14 +22,14 @@ const downloads: React.FC = () => {
|
||||
queryKey: ["downloaded_files", process?.item.Id],
|
||||
queryFn: async () =>
|
||||
JSON.parse(
|
||||
(await AsyncStorage.getItem("downloaded_files")) || "[]",
|
||||
(await AsyncStorage.getItem("downloaded_files")) || "[]"
|
||||
) as BaseItemDto[],
|
||||
staleTime: 0,
|
||||
});
|
||||
|
||||
const movies = useMemo(
|
||||
() => downloadedFiles?.filter((f) => f.Type === "Movie") || [],
|
||||
[downloadedFiles],
|
||||
[downloadedFiles]
|
||||
);
|
||||
|
||||
const groupedBySeries = useMemo(() => {
|
||||
@@ -61,7 +56,7 @@ const downloads: React.FC = () => {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<View className="h-full flex flex-col items-center justify-center -mt-6">
|
||||
<ActivityIndicator size="small" color="white" />
|
||||
<Loader />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
playingAtom,
|
||||
} from "@/components/CurrentlyPlayingBar";
|
||||
import { DownloadItem } from "@/components/DownloadItem";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import { OverviewText } from "@/components/OverviewText";
|
||||
import { PlayButton } from "@/components/PlayButton";
|
||||
import { PlayedStatus } from "@/components/PlayedStatus";
|
||||
@@ -34,7 +35,7 @@ import { Image } from "expo-image";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { ActivityIndicator, ScrollView, View } from "react-native";
|
||||
import { View } from "react-native";
|
||||
import CastContext, {
|
||||
PlayServicesState,
|
||||
useCastDevice,
|
||||
@@ -194,7 +195,7 @@ const page: React.FC = () => {
|
||||
if (l1)
|
||||
return (
|
||||
<View className="justify-center items-center h-full">
|
||||
<ActivityIndicator />
|
||||
<Loader />
|
||||
</View>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,37 +1,38 @@
|
||||
import { AudioTrackSelector } from "@/components/AudioTrackSelector";
|
||||
import { Bitrate, BitrateSelector } from "@/components/BitrateSelector";
|
||||
import { Chromecast } from "@/components/Chromecast";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import {
|
||||
currentlyPlayingItemAtom,
|
||||
playingAtom,
|
||||
} from "@/components/CurrentlyPlayingBar";
|
||||
import { DownloadItem } from "@/components/DownloadItem";
|
||||
import { Loader } from "@/components/Loader";
|
||||
import { MoviesTitleHeader } from "@/components/movies/MoviesTitleHeader";
|
||||
import { ParallaxScrollView } from "@/components/ParallaxPage";
|
||||
import { PlayButton } from "@/components/PlayButton";
|
||||
import { NextEpisodeButton } from "@/components/series/NextEpisodeButton";
|
||||
import { SimilarItems } from "@/components/SimilarItems";
|
||||
import { SubtitleTrackSelector } from "@/components/SubtitleTrackSelector";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl";
|
||||
import { getLogoImageUrlById } from "@/utils/jellyfin/image/getLogoImageUrlById";
|
||||
import { getStreamUrl } from "@/utils/jellyfin/media/getStreamUrl";
|
||||
import { getUserItemData } from "@/utils/jellyfin/user-library/getUserItemData";
|
||||
import { chromecastProfile } from "@/utils/profiles/chromecast";
|
||||
import ios from "@/utils/profiles/ios";
|
||||
import { getMediaInfoApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Image } from "expo-image";
|
||||
import { useLocalSearchParams, useNavigation } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { ActivityIndicator, ScrollView, View } from "react-native";
|
||||
import { getUserItemData } from "@/utils/jellyfin/user-library/getUserItemData";
|
||||
import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl";
|
||||
import { getLogoImageUrlById } from "@/utils/jellyfin/image/getLogoImageUrlById";
|
||||
import { PlayButton } from "@/components/PlayButton";
|
||||
import { Bitrate, BitrateSelector } from "@/components/BitrateSelector";
|
||||
import { getMediaInfoApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { getStreamUrl } from "@/utils/jellyfin/media/getStreamUrl";
|
||||
import { ScrollView, View } from "react-native";
|
||||
import CastContext, {
|
||||
PlayServicesState,
|
||||
useCastDevice,
|
||||
useRemoteMediaClient,
|
||||
} from "react-native-google-cast";
|
||||
import { chromecastProfile } from "@/utils/profiles/chromecast";
|
||||
import {
|
||||
currentlyPlayingItemAtom,
|
||||
playingAtom,
|
||||
} from "@/components/CurrentlyPlayingBar";
|
||||
import { AudioTrackSelector } from "@/components/AudioTrackSelector";
|
||||
import { SubtitleTrackSelector } from "@/components/SubtitleTrackSelector";
|
||||
import { NextEpisodeButton } from "@/components/series/NextEpisodeButton";
|
||||
import { MoviesTitleHeader } from "@/components/movies/MoviesTitleHeader";
|
||||
import { ParallaxScrollView } from "@/components/ParallaxPage";
|
||||
import { Chromecast } from "@/components/Chromecast";
|
||||
import ios from "@/utils/profiles/ios";
|
||||
|
||||
const page: React.FC = () => {
|
||||
const local = useLocalSearchParams();
|
||||
@@ -84,12 +85,12 @@ const page: React.FC = () => {
|
||||
quality: 90,
|
||||
width: 1000,
|
||||
}),
|
||||
[item],
|
||||
[item]
|
||||
);
|
||||
|
||||
const logoUrl = useMemo(
|
||||
() => (item?.Type === "Movie" ? getLogoImageUrlById({ api, item }) : null),
|
||||
[item],
|
||||
[item]
|
||||
);
|
||||
|
||||
const { data: sessionData } = useQuery({
|
||||
@@ -173,13 +174,13 @@ const page: React.FC = () => {
|
||||
setPlaying(true);
|
||||
}
|
||||
},
|
||||
[playbackUrl, item],
|
||||
[playbackUrl, item]
|
||||
);
|
||||
|
||||
if (l1)
|
||||
return (
|
||||
<View className="justify-center items-center h-full">
|
||||
<ActivityIndicator />
|
||||
<Loader />
|
||||
</View>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { PropsWithChildren, ReactNode, useMemo } from "react";
|
||||
import { TouchableOpacity, Text, ActivityIndicator, View } from "react-native";
|
||||
import * as Haptics from "expo-haptics";
|
||||
import React, { PropsWithChildren, ReactNode, useMemo } from "react";
|
||||
import { Text, TouchableOpacity, View } from "react-native";
|
||||
import { Loader } from "./Loader";
|
||||
|
||||
interface ButtonProps extends React.ComponentProps<typeof TouchableOpacity> {
|
||||
onPress?: () => void;
|
||||
@@ -57,7 +58,7 @@ export const Button: React.FC<PropsWithChildren<ButtonProps>> = ({
|
||||
{...props}
|
||||
>
|
||||
{loading ? (
|
||||
<ActivityIndicator color={"white"} size={24} />
|
||||
<Loader />
|
||||
) : (
|
||||
<View
|
||||
className={`
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl";
|
||||
import { getAuthHeaders } from "@/utils/jellyfin/jellyfin";
|
||||
import { reportPlaybackProgress } from "@/utils/jellyfin/playstate/reportPlaybackProgress";
|
||||
@@ -14,13 +13,7 @@ import { BlurView } from "expo-blur";
|
||||
import { useRouter, useSegments } from "expo-router";
|
||||
import { atom, useAtom } from "jotai";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Platform,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { Alert, Platform, TouchableOpacity, View } from "react-native";
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
@@ -28,6 +21,7 @@ import Animated, {
|
||||
} from "react-native-reanimated";
|
||||
import Video, { OnProgressData, VideoRef } from "react-native-video";
|
||||
import { Text } from "./common/Text";
|
||||
import { Loader } from "./Loader";
|
||||
|
||||
export const currentlyPlayingItemAtom = atom<{
|
||||
item: BaseItemDto;
|
||||
@@ -292,7 +286,7 @@ export const CurrentlyPlayingBar: React.FC = () => {
|
||||
renderLoader={
|
||||
item?.Type !== "Audio" && (
|
||||
<View className="flex flex-col items-center justify-center h-full">
|
||||
<ActivityIndicator size={"small"} color={"white"} />
|
||||
<Loader />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { router } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { ActivityIndicator, TouchableOpacity, View } from "react-native";
|
||||
import { TouchableOpacity, View } from "react-native";
|
||||
import { Loader } from "./Loader";
|
||||
import ProgressCircle from "./ProgressCircle";
|
||||
|
||||
type DownloadProps = {
|
||||
@@ -39,7 +40,7 @@ export const DownloadItem: React.FC<DownloadProps> = ({
|
||||
if (!item.Id) return false;
|
||||
|
||||
const data: BaseItemDto[] = JSON.parse(
|
||||
(await AsyncStorage.getItem("downloaded_files")) || "[]",
|
||||
(await AsyncStorage.getItem("downloaded_files")) || "[]"
|
||||
);
|
||||
|
||||
return data.some((d) => d.Id === item.Id);
|
||||
@@ -50,7 +51,7 @@ export const DownloadItem: React.FC<DownloadProps> = ({
|
||||
if (isLoading || isLoadingDownloaded) {
|
||||
return (
|
||||
<View className="rounded h-10 aspect-square flex items-center justify-center">
|
||||
<ActivityIndicator size={"small"} color={"white"} />
|
||||
<Loader />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -72,7 +73,7 @@ export const DownloadItem: React.FC<DownloadProps> = ({
|
||||
>
|
||||
<View className="rounded h-10 aspect-square flex items-center justify-center">
|
||||
{process.progress === 0 ? (
|
||||
<ActivityIndicator size={"small"} color={"white"} />
|
||||
<Loader />
|
||||
) : (
|
||||
<View className="-rotate-45">
|
||||
<ProgressCircle
|
||||
|
||||
18
components/Loader.tsx
Normal file
18
components/Loader.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import {
|
||||
ActivityIndicator,
|
||||
ActivityIndicatorProps,
|
||||
Platform,
|
||||
View,
|
||||
} from "react-native";
|
||||
|
||||
interface Props extends ActivityIndicatorProps {}
|
||||
|
||||
export const Loader: React.FC<Props> = ({ ...props }) => {
|
||||
return (
|
||||
<ActivityIndicator
|
||||
size={"small"}
|
||||
color={Platform.OS === "ios" ? "white" : "#9333ea"}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
import { ActivityIndicator, View } from "react-native";
|
||||
|
||||
export const Loading: React.FC = () => {
|
||||
return (
|
||||
<View>
|
||||
<ActivityIndicator />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -6,14 +6,10 @@ import { useQuery } from "@tanstack/react-query";
|
||||
import { router } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { useMemo } from "react";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { ItemCardText } from "./ItemCardText";
|
||||
import { ScrollView, TouchableOpacity, View } from "react-native";
|
||||
import { Text } from "./common/Text";
|
||||
import { ItemCardText } from "./ItemCardText";
|
||||
import { Loader } from "./Loader";
|
||||
|
||||
type SimilarItemsProps = {
|
||||
itemId: string;
|
||||
@@ -49,7 +45,7 @@ export const SimilarItems: React.FC<SimilarItemsProps> = ({ itemId }) => {
|
||||
<Text className="px-4 text-2xl font-bold mb-2">Similar items</Text>
|
||||
{isLoading ? (
|
||||
<View className="my-12">
|
||||
<ActivityIndicator />
|
||||
<Loader />
|
||||
</View>
|
||||
) : (
|
||||
<ScrollView horizontal>
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import React, { useEffect } from "react";
|
||||
import {
|
||||
ScrollView,
|
||||
View,
|
||||
ViewStyle,
|
||||
ActivityIndicator,
|
||||
ScrollViewProps,
|
||||
} from "react-native";
|
||||
import { ScrollView, ScrollViewProps, View, ViewStyle } from "react-native";
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
withTiming,
|
||||
} from "react-native-reanimated";
|
||||
import { Loader } from "../Loader";
|
||||
import { Text } from "./Text";
|
||||
|
||||
interface HorizontalScrollProps<T> extends ScrollViewProps {
|
||||
@@ -58,7 +53,7 @@ export function HorizontalScroll<T>({
|
||||
loadingContainerStyle,
|
||||
]}
|
||||
>
|
||||
<ActivityIndicator size="small" />
|
||||
<Loader />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { ActivityIndicator, View, ViewProps } from "react-native";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl";
|
||||
import { getLogoImageUrlById } from "@/utils/jellyfin/image/getLogoImageUrlById";
|
||||
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { Image } from "expo-image";
|
||||
import { useRouter } from "expo-router";
|
||||
import { useAtom } from "jotai";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { Dimensions } from "react-native";
|
||||
import React, { useMemo } from "react";
|
||||
import { Dimensions, View, ViewProps } from "react-native";
|
||||
import { useSharedValue } from "react-native-reanimated";
|
||||
import Carousel, {
|
||||
ICarouselInstance,
|
||||
Pagination,
|
||||
} from "react-native-reanimated-carousel";
|
||||
import React, { useMemo } from "react";
|
||||
import { Image } from "expo-image";
|
||||
import { getLogoImageUrlById } from "@/utils/jellyfin/image/getLogoImageUrlById";
|
||||
import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl";
|
||||
import { TouchableItemRouter } from "../common/TouchableItemRouter";
|
||||
import { Loader } from "../Loader";
|
||||
|
||||
interface Props extends ViewProps {}
|
||||
|
||||
@@ -84,7 +84,7 @@ export const LargeMovieCarousel: React.FC<Props> = ({ ...props }) => {
|
||||
if (l1 || l2)
|
||||
return (
|
||||
<View className="h-[242px] flex items-center justify-center">
|
||||
<ActivityIndicator size={"small"} color="#fff" />
|
||||
<Loader />
|
||||
</View>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Linking,
|
||||
Switch,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { Text } from "../common/Text";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import * as DropdownMenu from "zeego/dropdown-menu";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useAtom } from "jotai";
|
||||
import { useState } from "react";
|
||||
import { Linking, Switch, TouchableOpacity, View } from "react-native";
|
||||
import * as DropdownMenu from "zeego/dropdown-menu";
|
||||
import { Text } from "../common/Text";
|
||||
import { Loader } from "../Loader";
|
||||
|
||||
export const SettingToggles: React.FC = () => {
|
||||
const [settings, updateSettings] = useSettings();
|
||||
@@ -83,7 +77,7 @@ export const SettingToggles: React.FC = () => {
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
Linking.openURL(
|
||||
"https://github.com/lostb1t/jellyfin-plugin-media-lists",
|
||||
"https://github.com/lostb1t/jellyfin-plugin-media-lists"
|
||||
);
|
||||
}}
|
||||
>
|
||||
@@ -121,7 +115,7 @@ export const SettingToggles: React.FC = () => {
|
||||
mediaListCollectionIds:
|
||||
settings?.mediaListCollectionIds.includes(mlc.Id!)
|
||||
? settings?.mediaListCollectionIds.filter(
|
||||
(id) => id !== mlc.Id,
|
||||
(id) => id !== mlc.Id
|
||||
)
|
||||
: [...settings?.mediaListCollectionIds, mlc.Id!],
|
||||
});
|
||||
@@ -131,7 +125,7 @@ export const SettingToggles: React.FC = () => {
|
||||
))}
|
||||
{isLoadingMediaListCollections && (
|
||||
<View className="flex flex-row items-center justify-center bg-neutral-900 p-4">
|
||||
<ActivityIndicator size="small" color="#fff" />
|
||||
<Loader />
|
||||
</View>
|
||||
)}
|
||||
{mediaListCollections?.length === 0 && (
|
||||
|
||||
Reference in New Issue
Block a user