mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
updated buffer percentage formula
This commit is contained in:
@@ -1,13 +1,18 @@
|
|||||||
import styled, { css } from 'styled-components'
|
|
||||||
import { NoImageIcon } from 'icons'
|
import { NoImageIcon } from 'icons'
|
||||||
import { getPeerString, humanizeSize } from 'utils/Utils'
|
import { getPeerString, humanizeSize } from 'utils/Utils'
|
||||||
// import { viewedHost } from 'utils/Hosts'
|
|
||||||
import { CopyToClipboard } from 'react-copy-to-clipboard'
|
import { CopyToClipboard } from 'react-copy-to-clipboard'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Button } from '@material-ui/core'
|
import { Button, ButtonGroup, Typography } from '@material-ui/core'
|
||||||
import { ArrowDownward, ArrowUpward, SwapVerticalCircle, ViewAgenda } from '@material-ui/icons'
|
import {
|
||||||
|
ArrowDownward as ArrowDownwardIcon,
|
||||||
|
ArrowUpward as ArrowUpwardIcon,
|
||||||
|
SwapVerticalCircle as SwapVerticalCircleIcon,
|
||||||
|
ViewAgenda as ViewAgendaIcon,
|
||||||
|
Cached as CachedIcon,
|
||||||
|
} from '@material-ui/icons'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { torrentsHost } from 'utils/Hosts'
|
import { streamHost, torrentsHost, viewedHost } from 'utils/Hosts'
|
||||||
|
import { GETTING_INFO, IN_DB } from 'torrentStates'
|
||||||
|
|
||||||
import { useUpdateCache, useCreateCacheMap, useGetSettings } from './customHooks'
|
import { useUpdateCache, useCreateCacheMap, useGetSettings } from './customHooks'
|
||||||
import DialogHeader from './DialogHeader'
|
import DialogHeader from './DialogHeader'
|
||||||
@@ -35,32 +40,56 @@ const shortenText = (text, count) => text.slice(0, count) + (text.length > count
|
|||||||
export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
const [isDetailedCacheView, setIsDetailedCacheView] = useState(false)
|
const [isDetailedCacheView, setIsDetailedCacheView] = useState(false)
|
||||||
|
const [viewedFileList, setViewedFileList] = useState()
|
||||||
|
const [playableFileList, setPlayableFileList] = useState()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
poster,
|
poster,
|
||||||
hash,
|
hash,
|
||||||
title,
|
title,
|
||||||
name,
|
name,
|
||||||
|
stat,
|
||||||
download_speed: downloadSpeed,
|
download_speed: downloadSpeed,
|
||||||
upload_speed: uploadSpeed,
|
upload_speed: uploadSpeed,
|
||||||
stat_string: statString,
|
stat_string: statString,
|
||||||
torrent_size: torrentSize,
|
torrent_size: torrentSize,
|
||||||
|
file_stats: torrentFileList,
|
||||||
} = torrent
|
} = torrent
|
||||||
|
|
||||||
const cache = useUpdateCache(hash)
|
const cache = useUpdateCache(hash)
|
||||||
const cacheMap = useCreateCacheMap(cache)
|
const cacheMap = useCreateCacheMap(cache)
|
||||||
const settings = useGetSettings(cache)
|
const settings = useGetSettings(cache)
|
||||||
|
|
||||||
const dropTorrent = hash => axios.post(torrentsHost(), { action: 'drop', hash })
|
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 { Capacity, PiecesCount, PiecesLength, Filled } = cache
|
const { Capacity, PiecesCount, PiecesLength, Filled } = cache
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setPlayableFileList(torrentFileList?.filter(file => playableExtList.includes(getExt(file.path))))
|
||||||
|
}, [torrentFileList])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const cacheLoaded = !!Object.entries(cache).length
|
const cacheLoaded = !!Object.entries(cache).length
|
||||||
const torrentLoaded = torrent.stat_string !== 'Torrent in db' && torrent.stat_string !== 'Torrent getting info'
|
const torrentLoaded = stat !== GETTING_INFO && stat !== IN_DB
|
||||||
|
|
||||||
if (!cacheLoaded && !isLoading) setIsLoading(true)
|
if (!cacheLoaded && !isLoading) setIsLoading(true)
|
||||||
if (cacheLoaded && isLoading && torrentLoaded) setIsLoading(false)
|
if (cacheLoaded && isLoading && torrentLoaded) setIsLoading(false)
|
||||||
}, [torrent, cache, isLoading])
|
}, [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)
|
||||||
|
setViewedFileList(lst)
|
||||||
|
} else setViewedFileList()
|
||||||
|
})
|
||||||
|
}, [hash])
|
||||||
|
|
||||||
const bufferSize = settings?.PreloadBuffer ? Capacity : 33554432 // Default is 32mb if PreloadBuffer is false
|
const bufferSize = settings?.PreloadBuffer ? Capacity : 33554432 // Default is 32mb if PreloadBuffer is false
|
||||||
|
|
||||||
@@ -105,7 +134,7 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
value={humanizeSize(downloadSpeed) || '0 B'}
|
value={humanizeSize(downloadSpeed) || '0 B'}
|
||||||
iconBg='#118f00'
|
iconBg='#118f00'
|
||||||
valueBg='#13a300'
|
valueBg='#13a300'
|
||||||
icon={ArrowDownward}
|
icon={ArrowDownwardIcon}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatisticsField
|
<StatisticsField
|
||||||
@@ -113,7 +142,7 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
value={humanizeSize(uploadSpeed) || '0 B'}
|
value={humanizeSize(uploadSpeed) || '0 B'}
|
||||||
iconBg='#0146ad'
|
iconBg='#0146ad'
|
||||||
valueBg='#0058db'
|
valueBg='#0058db'
|
||||||
icon={ArrowUpward}
|
icon={ArrowUpwardIcon}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatisticsField
|
<StatisticsField
|
||||||
@@ -121,7 +150,7 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
value={getPeerString(torrent)}
|
value={getPeerString(torrent)}
|
||||||
iconBg='#0146ad'
|
iconBg='#0146ad'
|
||||||
valueBg='#0058db'
|
valueBg='#0058db'
|
||||||
icon={SwapVerticalCircle}
|
icon={SwapVerticalCircleIcon}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatisticsField
|
<StatisticsField
|
||||||
@@ -129,7 +158,7 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
value={humanizeSize(torrentSize)}
|
value={humanizeSize(torrentSize)}
|
||||||
iconBg='#0146ad'
|
iconBg='#0146ad'
|
||||||
valueBg='#0058db'
|
valueBg='#0058db'
|
||||||
icon={ViewAgenda}
|
icon={ViewAgendaIcon}
|
||||||
/>
|
/>
|
||||||
</StatisticsWrapper>
|
</StatisticsWrapper>
|
||||||
</TorrentData>
|
</TorrentData>
|
||||||
@@ -141,7 +170,11 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
{!settings?.PreloadBuffer && (
|
{!settings?.PreloadBuffer && (
|
||||||
<SectionSubName>Enable "Preload Buffer" in settings to change buffer size</SectionSubName>
|
<SectionSubName>Enable "Preload Buffer" in settings to change buffer size</SectionSubName>
|
||||||
)}
|
)}
|
||||||
<LoadingProgress value={Filled} fullAmount={bufferSize} label={humanizeSize(bufferSize)} />
|
<LoadingProgress
|
||||||
|
value={Filled}
|
||||||
|
fullAmount={bufferSize}
|
||||||
|
label={`${humanizeSize(Filled) || '0 B'} / ${humanizeSize(bufferSize)}`}
|
||||||
|
/>
|
||||||
</SectionHeader>
|
</SectionHeader>
|
||||||
|
|
||||||
<TorrentCache isMini cache={cache} cacheMap={cacheMap} />
|
<TorrentCache isMini cache={cache} cacheMap={cacheMap} />
|
||||||
@@ -166,9 +199,9 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
</ButtonSectionButton>
|
</ButtonSectionButton>
|
||||||
</CopyToClipboard>
|
</CopyToClipboard>
|
||||||
|
|
||||||
<ButtonSectionButton>remove views</ButtonSectionButton>
|
<ButtonSectionButton onClick={() => removeTorrentViews()}>remove views</ButtonSectionButton>
|
||||||
|
|
||||||
<ButtonSectionButton onClick={() => dropTorrent(hash)}>drop torrent</ButtonSectionButton>
|
<ButtonSectionButton onClick={() => dropTorrent()}>drop torrent</ButtonSectionButton>
|
||||||
|
|
||||||
<ButtonSectionButton>download playlist</ButtonSectionButton>
|
<ButtonSectionButton>download playlist</ButtonSectionButton>
|
||||||
|
|
||||||
@@ -177,6 +210,26 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
|
|
||||||
<TorrentFilesSection>
|
<TorrentFilesSection>
|
||||||
<SectionTitle>Torrent Content</SectionTitle>
|
<SectionTitle>Torrent Content</SectionTitle>
|
||||||
|
|
||||||
|
{!playableFileList?.length
|
||||||
|
? 'No playable files in this torrent'
|
||||||
|
: playableFileList.map(({ id, path, length }) => (
|
||||||
|
<ButtonGroup key={id} disableElevation variant='contained' color='primary'>
|
||||||
|
<Button>
|
||||||
|
<a href={getFileLink(path, id)}>
|
||||||
|
<Typography>
|
||||||
|
{path.split('\\').pop().split('/').pop()} | {humanizeSize(length)}{' '}
|
||||||
|
{viewedFileList && viewedFileList?.indexOf(id) !== -1 && '| ✓'}
|
||||||
|
</Typography>
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button onClick={() => preloadBuffer(id)}>
|
||||||
|
<CachedIcon />
|
||||||
|
<Typography>Preload</Typography>
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
))}
|
||||||
</TorrentFilesSection>
|
</TorrentFilesSection>
|
||||||
</DialogContentGrid>
|
</DialogContentGrid>
|
||||||
)}
|
)}
|
||||||
@@ -184,117 +237,68 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// function getPreload(torrent) {
|
function getExt(filename) {
|
||||||
// if (torrent.preloaded_bytes > 0 && torrent.preload_size > 0 && torrent.preloaded_bytes < torrent.preload_size) {
|
const ext = filename.split('.').pop()
|
||||||
// const progress = ((torrent.preloaded_bytes * 100) / torrent.preload_size).toFixed(2)
|
if (ext === filename) return ''
|
||||||
// return `${humanizeSize(torrent.preloaded_bytes)} / ${humanizeSize(torrent.preload_size)} ${progress}%`
|
return ext.toLowerCase()
|
||||||
// }
|
}
|
||||||
|
const playableExtList = [
|
||||||
// if (!torrent.preloaded_bytes) return humanizeSize(0)
|
// video
|
||||||
|
'3g2',
|
||||||
// return humanizeSize(torrent.preloaded_bytes)
|
'3gp',
|
||||||
// }
|
'aaf',
|
||||||
|
'asf',
|
||||||
// function remViews(hash) {
|
'avchd',
|
||||||
// try {
|
'avi',
|
||||||
// if (hash)
|
'drc',
|
||||||
// fetch(viewedHost(), {
|
'flv',
|
||||||
// method: 'post',
|
'iso',
|
||||||
// body: JSON.stringify({ action: 'rem', hash, file_index: -1 }),
|
'm2v',
|
||||||
// headers: {
|
'm2ts',
|
||||||
// Accept: 'application/json, text/plain, */*',
|
'm4p',
|
||||||
// 'Content-Type': 'application/json',
|
'm4v',
|
||||||
// },
|
'mkv',
|
||||||
// })
|
'mng',
|
||||||
// } catch (e) {
|
'mov',
|
||||||
// console.error(e)
|
'mp2',
|
||||||
// }
|
'mp4',
|
||||||
// }
|
'mpe',
|
||||||
|
'mpeg',
|
||||||
// function getViewed(hash, callback) {
|
'mpg',
|
||||||
// try {
|
'mpv',
|
||||||
// fetch(viewedHost(), {
|
'mxf',
|
||||||
// method: 'post',
|
'nsv',
|
||||||
// body: JSON.stringify({ action: 'list', hash }),
|
'ogg',
|
||||||
// headers: {
|
'ogv',
|
||||||
// Accept: 'application/json, text/plain, */*',
|
'ts',
|
||||||
// 'Content-Type': 'application/json',
|
'qt',
|
||||||
// },
|
'rm',
|
||||||
// })
|
'rmvb',
|
||||||
// .then(res => res.json())
|
'roq',
|
||||||
// .then(callback)
|
'svi',
|
||||||
// } catch (e) {
|
'vob',
|
||||||
// console.error(e)
|
'webm',
|
||||||
// }
|
'wmv',
|
||||||
// }
|
'yuv',
|
||||||
|
// audio
|
||||||
// function getPlayableFile(torrent) {
|
'aac',
|
||||||
// if (!torrent || !torrent.file_stats) return null
|
'aiff',
|
||||||
// return torrent.file_stats.filter(file => extPlayable.includes(getExt(file.path)))
|
'ape',
|
||||||
// }
|
'au',
|
||||||
|
'flac',
|
||||||
// function getExt(filename) {
|
'gsm',
|
||||||
// const ext = filename.split('.').pop()
|
'it',
|
||||||
// if (ext === filename) return ''
|
'm3u',
|
||||||
// return ext.toLowerCase()
|
'm4a',
|
||||||
// }
|
'mid',
|
||||||
// const extPlayable = [
|
'mod',
|
||||||
// // video
|
'mp3',
|
||||||
// '3g2',
|
'mpa',
|
||||||
// '3gp',
|
'pls',
|
||||||
// 'aaf',
|
'ra',
|
||||||
// 'asf',
|
's3m',
|
||||||
// 'avchd',
|
'sid',
|
||||||
// 'avi',
|
'wav',
|
||||||
// 'drc',
|
'wma',
|
||||||
// 'flv',
|
'xm',
|
||||||
// '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',
|
|
||||||
// ]
|
|
||||||
|
|||||||
@@ -166,14 +166,22 @@ export const StatisticsFieldValue = styled.div`
|
|||||||
`}
|
`}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const LoadingProgress = styled.div.attrs(({ value, fullAmount }) => ({
|
export const LoadingProgress = styled.div.attrs(({ value, fullAmount }) => {
|
||||||
percentage: Math.min(100, (value * 100) / fullAmount),
|
const percentage = (value * 100) / fullAmount
|
||||||
}))`
|
const percentageMinmax = Math.min(100, percentage)
|
||||||
${({ percentage, label }) => css`
|
// console.log(percentage)
|
||||||
|
const stylePercentage = percentageMinmax === 100 ? 100 : percentageMinmax % 100
|
||||||
|
|
||||||
|
return {
|
||||||
|
style: {
|
||||||
|
background: `linear-gradient(to right, #b5dec9 0%, #b5dec9 ${stylePercentage}%, #fff ${stylePercentage}%, #fff 100%)`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})`
|
||||||
|
${({ label }) => css`
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: linear-gradient(to right, #b5dec9 0%, #b5dec9 ${percentage}%, #fff ${percentage}%, #fff 100%);
|
|
||||||
|
|
||||||
:before {
|
:before {
|
||||||
content: '${label}';
|
content: '${label}';
|
||||||
|
|||||||
1
web/src/torrentStates.js
Normal file
1
web/src/torrentStates.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const [GETTING_INFO, PRELOAD, WORKING, CLOSED, IN_DB] = [1, 2, 3, 4, 5]
|
||||||
Reference in New Issue
Block a user