import { NoImageIcon } from 'icons' import { getPeerString, 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 { ArrowDownward as ArrowDownwardIcon, ArrowUpward as ArrowUpwardIcon, SwapVerticalCircle as SwapVerticalCircleIcon, ViewAgenda as ViewAgendaIcon, Widgets as WidgetsIcon, PhotoSizeSelectSmall as PhotoSizeSelectSmallIcon, Build as BuildIcon, } from '@material-ui/icons' import axios from 'axios' import { playlistTorrHost, streamHost, torrentsHost, viewedHost } from 'utils/Hosts' import { GETTING_INFO, IN_DB } from 'torrentStates' import { useUpdateCache, useCreateCacheMap, useGetSettings } from './customHooks' import DialogHeader from './DialogHeader' import TorrentCache from './TorrentCache' import { DetailedTorrentCacheViewWrapper, DialogContentGrid, MainSection, MainSectionButtonGroup, Poster, SectionTitle, SectionSubName, StatisticsWrapper, LoadingProgress, SectionHeader, CacheSection, TorrentFilesSection, Divider, SmallLabel, Table, } from './style' import StatisticsField from './StatisticsField' 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 ? ( 'loading' ) : isDetailedCacheView ? ( ) : ( {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', ]