import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; import { runningProcesses } from "@/utils/atoms/downloads"; import { getPlaybackInfo, useDownloadMedia } from "@/utils/jellyfin"; import Ionicons from "@expo/vector-icons/Ionicons"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { router } from "expo-router"; import { useAtom } from "jotai"; import { useCallback, useEffect, useState } from "react"; import { ActivityIndicator, TouchableOpacity, View } from "react-native"; import ProgressCircle from "./ProgressCircle"; import { Text } from "./common/Text"; import { useQuery } from "@tanstack/react-query"; type DownloadProps = { item: BaseItemDto; }; export const DownloadItem: React.FC = ({ item }) => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); const [process] = useAtom(runningProcesses); const { downloadMedia, isDownloading, error, cancelDownload } = useDownloadMedia(api, user?.Id); const { data: playbackInfo, isLoading } = useQuery({ queryKey: ["playbackInfo", item.Id], queryFn: async () => getPlaybackInfo(api, item.Id, user?.Id), }); const downloadFile = useCallback(async () => { if (!playbackInfo) return; const source = playbackInfo.MediaSources?.[0]; if (source?.SupportsDirectPlay && item.CanDownload) { downloadMedia(item); } else { throw new Error( "Direct play not supported thus the file cannot be downloaded" ); } }, [item, user, playbackInfo]); const [downloaded, setDownloaded] = useState(false); useEffect(() => { (async () => { const data: BaseItemDto[] = JSON.parse( (await AsyncStorage.getItem("downloaded_files")) || "[]" ); if (data.find((d) => d.Id === item.Id)) setDownloaded(true); })(); }, [process]); if (isLoading) { return ; } if (playbackInfo?.MediaSources?.[0].SupportsDirectPlay === false) { return ( ); } if (process && process.item.Id !== item.Id!) { return ( {}} style={{ opacity: 0.5 }}> ); } return ( {process ? ( { cancelDownload(); }} className="relative" > {process.progress.toFixed(0)}% ) : downloaded ? ( { router.push( `/(auth)/player/offline/page?url=${item.Id}.mp4&itemId=${item.Id}` ); }} > ) : ( { downloadFile(); }} > )} ); };