updated buffer percentage formula

This commit is contained in:
Daniel Shleifman
2021-05-28 23:29:07 +03:00
parent 611c529718
commit 5ec6396d52
3 changed files with 147 additions and 134 deletions

View File

@@ -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 &quot;Preload Buffer&quot; in settings to change buffer size</SectionSubName> <SectionSubName>Enable &quot;Preload Buffer&quot; 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',
// ]

View File

@@ -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
View File

@@ -0,0 +1 @@
export const [GETTING_INFO, PRELOAD, WORKING, CLOSED, IN_DB] = [1, 2, 3, 4, 5]