import { NoImageIcon } from 'icons' import { humanizeSize } from 'utils/Utils' import { CopyToClipboard } from 'react-copy-to-clipboard' import { useEffect, useState } from 'react' import { Button } from '@material-ui/core' import ptt from 'parse-torrent-title' import axios from 'axios' import { playlistTorrHost, streamHost, torrentsHost, viewedHost } from 'utils/Hosts' import { GETTING_INFO, IN_DB } from 'torrentStates' import CircularProgress from '@material-ui/core/CircularProgress' import { useUpdateCache, useCreateCacheMap, useGetSettings } from './customHooks' import DialogHeader from './DialogHeader' import TorrentCache from './TorrentCache' import { DetailedTorrentCacheViewWrapper, DialogContentGrid, MainSection, MainSectionButtonGroup, Poster, SectionTitle, SectionSubName, WidgetWrapper, LoadingProgress, SectionHeader, CacheSection, TorrentFilesSection, Divider, SmallLabel, Table, } from './style' import { DownlodSpeedWidget, UploadSpeedWidget, PeersWidget, SizeWidget, PiecesCountWidget, PiecesLengthWidget, StatusWidget, } from './widgets' const shortenText = (text, count) => text.slice(0, count) + (text.length > count ? '...' : '') export default function DialogTorrentDetailsContent({ closeDialog, torrent }) { const [isLoading, setIsLoading] = useState(true) const [isDetailedCacheView, setIsDetailedCacheView] = useState(false) const [viewedFileList, setViewedFileList] = useState() const [playableFileList, setPlayableFileList] = useState() const isOnlyOnePlayableFile = playableFileList?.length === 1 const latestViewedFileId = viewedFileList?.[viewedFileList?.length - 1] const latestViewedFile = playableFileList?.find(({ id }) => id === latestViewedFileId)?.path const latestViewedFileData = latestViewedFile && ptt.parse(latestViewedFile) const { poster, hash, title, name, stat, download_speed: downloadSpeed, upload_speed: uploadSpeed, stat_string: statString, torrent_size: torrentSize, file_stats: torrentFileList, } = torrent const cache = useUpdateCache(hash) const cacheMap = useCreateCacheMap(cache) const settings = useGetSettings(cache) const dropTorrent = () => axios.post(torrentsHost(), { action: 'drop', hash }) const removeTorrentViews = () => axios.post(viewedHost(), { action: 'rem', hash, file_index: -1 }).then(() => setViewedFileList()) const preloadBuffer = fileId => fetch(`${streamHost()}?link=${hash}&index=${fileId}&preload`) const getFileLink = (path, id) => `${streamHost()}/${encodeURIComponent(path.split('\\').pop().split('/').pop())}?link=${hash}&index=${id}&play` const fullPlaylistLink = `${playlistTorrHost()}/${encodeURIComponent(name || title || 'file')}.m3u?link=${hash}&m3u` const partialPlaylistLink = `${fullPlaylistLink}&fromlast` const fileHasEpisodeText = !!playableFileList?.find(({ path }) => ptt.parse(path).episode) const fileHasSeasonText = !!playableFileList?.find(({ path }) => ptt.parse(path).season) const fileHasResolutionText = !!playableFileList?.find(({ path }) => ptt.parse(path).resolution) const { Capacity, PiecesCount, PiecesLength, Filled } = cache useEffect(() => { setPlayableFileList(torrentFileList?.filter(file => playableExtList.includes(getExt(file.path)))) }, [torrentFileList]) useEffect(() => { const cacheLoaded = !!Object.entries(cache).length const torrentLoaded = stat !== GETTING_INFO && stat !== IN_DB if (!cacheLoaded && !isLoading) setIsLoading(true) if (cacheLoaded && isLoading && torrentLoaded) setIsLoading(false) }, [stat, cache, isLoading]) useEffect(() => { // getting viewed file list axios.post(viewedHost(), { action: 'list', hash }).then(({ data }) => { if (data) { const lst = data.map(itm => itm.file_index).sort((a, b) => a - b) setViewedFileList(lst) } else setViewedFileList() }) }, [hash]) const bufferSize = settings?.PreloadBuffer ? Capacity : 33554432 // Default is 32mb if PreloadBuffer is false return ( <> setIsDetailedCacheView(false) })} />
{isLoading ? (
) : isDetailedCacheView ? (
Data
Cache
) : ( {poster ? poster : }
{name && name !== title ? ( <> {shortenText(name, 50)} {shortenText(title, 160)} ) : ( {shortenText(title, 50)} )} {!isOnlyOnePlayableFile && !!viewedFileList?.length && ( <> Download Playlist Latest file played: {latestViewedFileData.title}. {latestViewedFileData.season && ( <> {' '} Season: {latestViewedFileData.season}. Episode: {latestViewedFileData.episode}. )} )} Torrent State Info {(isOnlyOnePlayableFile || !viewedFileList?.length) && ( )}
Buffer {!settings?.PreloadBuffer && ( Enable "Preload Buffer" in settings to change buffer size )} Torrent Content {!playableFileList?.length ? ( 'No playable files in this torrent' ) : ( <> {fileHasSeasonText && } {fileHasEpisodeText && } {fileHasResolutionText && } {playableFileList.map(({ id, path, length }) => { const { title, resolution, episode, season } = ptt.parse(path) const isViewed = viewedFileList?.includes(id) const link = getFileLink(path, id) return ( {fileHasSeasonText && } {fileHasEpisodeText && } {fileHasResolutionText && } ) })}
viewed nameseasonepisoderesolutionsize actions
{title}{season}{episode}{resolution}{humanizeSize(length)}
)}
)}
) } function getExt(filename) { const ext = filename.split('.').pop() if (ext === filename) return '' return ext.toLowerCase() } const playableExtList = [ // video '3g2', '3gp', 'aaf', 'asf', 'avchd', 'avi', 'drc', 'flv', 'iso', 'm2v', 'm2ts', 'm4p', 'm4v', 'mkv', 'mng', 'mov', 'mp2', 'mp4', 'mpe', 'mpeg', 'mpg', 'mpv', 'mxf', 'nsv', 'ogg', 'ogv', 'ts', 'qt', 'rm', 'rmvb', 'roq', 'svi', 'vob', 'webm', 'wmv', 'yuv', // audio 'aac', 'aiff', 'ape', 'au', 'flac', 'gsm', 'it', 'm3u', 'm4a', 'mid', 'mod', 'mp3', 'mpa', 'pls', 'ra', 's3m', 'sid', 'wav', 'wma', 'xm', ]