mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
added more widgets
This commit is contained in:
@@ -1,53 +0,0 @@
|
|||||||
import { Rect } from 'react-konva'
|
|
||||||
|
|
||||||
export default function SingleBlock({
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
percentage,
|
|
||||||
isActive = false,
|
|
||||||
inProgress = false,
|
|
||||||
isReaderRange = false,
|
|
||||||
isComplete = false,
|
|
||||||
boxHeight,
|
|
||||||
strokeWidth,
|
|
||||||
}) {
|
|
||||||
const strokeColor = isActive
|
|
||||||
? '#000'
|
|
||||||
: isComplete
|
|
||||||
? '#3fb57a'
|
|
||||||
: inProgress
|
|
||||||
? '#00d0d0'
|
|
||||||
: isReaderRange
|
|
||||||
? '#9a9aff'
|
|
||||||
: '#eef2f4'
|
|
||||||
const backgroundColor = inProgress ? '#00d0d0' : '#eef2f4'
|
|
||||||
const percentageProgressColor = '#3fb57a'
|
|
||||||
const processCompletedColor = '#3fb57a'
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Rect
|
|
||||||
x={x}
|
|
||||||
y={y}
|
|
||||||
stroke={strokeColor}
|
|
||||||
strokeWidth={strokeWidth}
|
|
||||||
height={boxHeight}
|
|
||||||
width={boxHeight}
|
|
||||||
fillAfterStrokeEnabled
|
|
||||||
preventDefault={false}
|
|
||||||
{...(isComplete
|
|
||||||
? { fill: processCompletedColor }
|
|
||||||
: inProgress && {
|
|
||||||
fillLinearGradientStartPointY: boxHeight,
|
|
||||||
fillLinearGradientEndPointY: 0,
|
|
||||||
fillLinearGradientColorStops: [
|
|
||||||
0,
|
|
||||||
percentageProgressColor,
|
|
||||||
percentage,
|
|
||||||
percentageProgressColor,
|
|
||||||
percentage,
|
|
||||||
backgroundColor,
|
|
||||||
],
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react'
|
|
||||||
import Typography from '@material-ui/core/Typography'
|
|
||||||
import DialogTitle from '@material-ui/core/DialogTitle'
|
|
||||||
import DialogContent from '@material-ui/core/DialogContent'
|
|
||||||
import { getPeerString, humanizeSize } from 'utils/Utils'
|
|
||||||
import { Stage, Layer } from 'react-konva'
|
|
||||||
import Measure from 'react-measure'
|
|
||||||
import { useUpdateCache, useCreateCacheMap } from 'components/DialogTorrentDetailsContent/customHooks'
|
|
||||||
|
|
||||||
import SingleBlock from './SingleBlock'
|
|
||||||
|
|
||||||
export default function DialogCacheInfo({ hash }) {
|
|
||||||
const [dimensions, setDimensions] = useState({ width: -1, height: -1 })
|
|
||||||
const [isShortView, setIsShortView] = useState(true)
|
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
|
||||||
const [stageSettings, setStageSettings] = useState({
|
|
||||||
boxHeight: null,
|
|
||||||
strokeWidth: null,
|
|
||||||
marginBetweenBlocks: null,
|
|
||||||
stageOffset: null,
|
|
||||||
})
|
|
||||||
|
|
||||||
const cache = useUpdateCache(hash)
|
|
||||||
const cacheMap = useCreateCacheMap(cache, () => setIsLoading(false))
|
|
||||||
|
|
||||||
const updateStageSettings = (boxHeight, strokeWidth) => {
|
|
||||||
setStageSettings({
|
|
||||||
boxHeight,
|
|
||||||
strokeWidth,
|
|
||||||
marginBetweenBlocks: strokeWidth,
|
|
||||||
stageOffset: strokeWidth * 2,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// initializing stageSettings
|
|
||||||
updateStageSettings(24, 4)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const { boxHeight, strokeWidth, marginBetweenBlocks, stageOffset } = stageSettings
|
|
||||||
|
|
||||||
const preloadPiecesAmount = Math.round(cache.Capacity / cache.PiecesLength - 1)
|
|
||||||
const blockSizeWithMargin = boxHeight + strokeWidth + marginBetweenBlocks
|
|
||||||
const piecesInOneRow = Math.floor((dimensions.width * 0.9) / blockSizeWithMargin)
|
|
||||||
const amountOfBlocksToRenderInShortView =
|
|
||||||
preloadPiecesAmount === piecesInOneRow
|
|
||||||
? preloadPiecesAmount - 1
|
|
||||||
: preloadPiecesAmount + piecesInOneRow - (preloadPiecesAmount % piecesInOneRow) - 1
|
|
||||||
const amountOfRows = Math.ceil((isShortView ? amountOfBlocksToRenderInShortView : cacheMap.length) / piecesInOneRow)
|
|
||||||
let activeId = null
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Measure bounds onResize={contentRect => setDimensions(contentRect.bounds)}>
|
|
||||||
{({ measureRef }) => (
|
|
||||||
<div ref={measureRef}>
|
|
||||||
<DialogTitle id='form-dialog-title'>
|
|
||||||
<Typography>
|
|
||||||
<b>Hash </b> <span style={{ wordBreak: 'break-word' }}>{cache.Hash}</span>
|
|
||||||
<br />
|
|
||||||
<b>Capacity </b> {humanizeSize(cache.Capacity)}
|
|
||||||
<br />
|
|
||||||
<b>Filled </b> {humanizeSize(cache.Filled)}
|
|
||||||
<br />
|
|
||||||
<b>Torrent size </b>{' '}
|
|
||||||
{cache.Torrent && cache.Torrent.torrent_size && humanizeSize(cache.Torrent.torrent_size)}
|
|
||||||
<br />
|
|
||||||
<b>Pieces length </b> {humanizeSize(cache.PiecesLength)}
|
|
||||||
<br />
|
|
||||||
<b>Pieces count </b> {cache.PiecesCount}
|
|
||||||
<br />
|
|
||||||
<b>Peers: </b> {getPeerString(cache.Torrent)}
|
|
||||||
<br />
|
|
||||||
<b>Download speed </b>{' '}
|
|
||||||
{cache.Torrent && cache.Torrent.download_speed ? `${humanizeSize(cache.Torrent.download_speed)}/sec` : ''}
|
|
||||||
<br />
|
|
||||||
<b>Upload speed </b>{' '}
|
|
||||||
{cache.Torrent && cache.Torrent.upload_speed ? `${humanizeSize(cache.Torrent.upload_speed)}/sec` : ''}
|
|
||||||
<br />
|
|
||||||
<b>Status </b> {cache.Torrent && cache.Torrent.stat_string && cache.Torrent.stat_string}
|
|
||||||
</Typography>
|
|
||||||
</DialogTitle>
|
|
||||||
|
|
||||||
<DialogContent>
|
|
||||||
<button
|
|
||||||
type='button'
|
|
||||||
onClick={() => {
|
|
||||||
if (isShortView) {
|
|
||||||
updateStageSettings(12, 2)
|
|
||||||
setIsShortView(false)
|
|
||||||
} else {
|
|
||||||
updateStageSettings(24, 4)
|
|
||||||
setIsShortView(true)
|
|
||||||
}
|
|
||||||
setIsLoading(true)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
updateStageSettings
|
|
||||||
</button>
|
|
||||||
{isLoading ? (
|
|
||||||
'loading'
|
|
||||||
) : (
|
|
||||||
<Stage
|
|
||||||
style={{ display: 'flex', justifyContent: 'center' }}
|
|
||||||
offset={{ x: -stageOffset, y: -stageOffset }}
|
|
||||||
width={stageOffset + blockSizeWithMargin * piecesInOneRow}
|
|
||||||
height={stageOffset + blockSizeWithMargin * amountOfRows}
|
|
||||||
>
|
|
||||||
<Layer>
|
|
||||||
{cacheMap.map(({ id, percentage, isComplete, inProgress, isActive, isReaderRange }) => {
|
|
||||||
const currentRow = Math.floor((isShortView ? id - activeId : id) / piecesInOneRow)
|
|
||||||
|
|
||||||
// -------- related only for short view -------
|
|
||||||
if (isActive) activeId = id
|
|
||||||
const shouldBeRendered =
|
|
||||||
isActive || (id - activeId <= amountOfBlocksToRenderInShortView && id - activeId >= 0)
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
return isShortView ? (
|
|
||||||
shouldBeRendered && (
|
|
||||||
<SingleBlock
|
|
||||||
key={id}
|
|
||||||
x={((id - activeId) % piecesInOneRow) * blockSizeWithMargin}
|
|
||||||
y={currentRow * blockSizeWithMargin}
|
|
||||||
percentage={percentage}
|
|
||||||
inProgress={inProgress}
|
|
||||||
isComplete={isComplete}
|
|
||||||
isReaderRange={isReaderRange}
|
|
||||||
isActive={isActive}
|
|
||||||
boxHeight={boxHeight}
|
|
||||||
strokeWidth={strokeWidth}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<SingleBlock
|
|
||||||
key={id}
|
|
||||||
x={(id % piecesInOneRow) * blockSizeWithMargin}
|
|
||||||
y={currentRow * blockSizeWithMargin}
|
|
||||||
percentage={percentage}
|
|
||||||
inProgress={inProgress}
|
|
||||||
isComplete={isComplete}
|
|
||||||
isReaderRange={isReaderRange}
|
|
||||||
isActive={isActive}
|
|
||||||
boxHeight={boxHeight}
|
|
||||||
strokeWidth={strokeWidth}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Layer>
|
|
||||||
</Stage>
|
|
||||||
)}
|
|
||||||
</DialogContent>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Measure>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
"Hash": "41e36c8de915d80db83fc134bee4e7e2d292657e",
|
|
||||||
"Capacity": 209715200,
|
|
||||||
"Filled": 2914808,
|
|
||||||
"PiecesLength": 4194304,
|
|
||||||
"PiecesCount": 2065,
|
|
||||||
"DownloadSpeed": 32770.860273455524,
|
|
||||||
"Pieces": {
|
|
||||||
"2064": {
|
|
||||||
"Id": 2064,
|
|
||||||
"Length": 2914808,
|
|
||||||
"Size": 162296,
|
|
||||||
"Completed": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -9,6 +9,9 @@ import {
|
|||||||
ArrowUpward as ArrowUpwardIcon,
|
ArrowUpward as ArrowUpwardIcon,
|
||||||
SwapVerticalCircle as SwapVerticalCircleIcon,
|
SwapVerticalCircle as SwapVerticalCircleIcon,
|
||||||
ViewAgenda as ViewAgendaIcon,
|
ViewAgenda as ViewAgendaIcon,
|
||||||
|
Widgets as WidgetsIcon,
|
||||||
|
PhotoSizeSelectSmall as PhotoSizeSelectSmallIcon,
|
||||||
|
Build as BuildIcon,
|
||||||
} from '@material-ui/icons'
|
} from '@material-ui/icons'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { playlistTorrHost, streamHost, torrentsHost, viewedHost } from 'utils/Hosts'
|
import { playlistTorrHost, streamHost, torrentsHost, viewedHost } from 'utils/Hosts'
|
||||||
@@ -117,9 +120,63 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
'loading'
|
'loading'
|
||||||
) : isDetailedCacheView ? (
|
) : isDetailedCacheView ? (
|
||||||
<DetailedTorrentCacheViewWrapper>
|
<DetailedTorrentCacheViewWrapper>
|
||||||
<div>PiecesCount: {PiecesCount}</div>
|
<StatisticsWrapper>
|
||||||
<div>PiecesLength: {humanizeSize(PiecesLength)}</div>
|
<StatisticsField
|
||||||
<div>status: {statString}</div>
|
title='Download speed'
|
||||||
|
value={humanizeSize(downloadSpeed) || '0 B'}
|
||||||
|
iconBg='#118f00'
|
||||||
|
valueBg='#13a300'
|
||||||
|
icon={ArrowDownwardIcon}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatisticsField
|
||||||
|
title='Upload speed'
|
||||||
|
value={humanizeSize(uploadSpeed) || '0 B'}
|
||||||
|
iconBg='#0146ad'
|
||||||
|
valueBg='#0058db'
|
||||||
|
icon={ArrowUpwardIcon}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatisticsField
|
||||||
|
title='Peers'
|
||||||
|
value={getPeerString(torrent)}
|
||||||
|
iconBg='#cdc118'
|
||||||
|
valueBg='#d8cb18'
|
||||||
|
icon={SwapVerticalCircleIcon}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatisticsField
|
||||||
|
title='Torrent size'
|
||||||
|
value={humanizeSize(torrentSize)}
|
||||||
|
iconBg='#01a292'
|
||||||
|
valueBg='#01ad9b'
|
||||||
|
icon={ViewAgendaIcon}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatisticsField
|
||||||
|
title='Pieces count'
|
||||||
|
value={PiecesCount}
|
||||||
|
iconBg='#b6c95e'
|
||||||
|
valueBg='#c0d076'
|
||||||
|
icon={WidgetsIcon}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatisticsField
|
||||||
|
title='Pieces length'
|
||||||
|
value={humanizeSize(PiecesLength)}
|
||||||
|
iconBg='#0982c8'
|
||||||
|
valueBg='#098cd7'
|
||||||
|
icon={PhotoSizeSelectSmallIcon}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatisticsField
|
||||||
|
title='Torrent status'
|
||||||
|
value={statString}
|
||||||
|
iconBg='#aea25b'
|
||||||
|
valueBg='#b4aa6e'
|
||||||
|
icon={BuildIcon}
|
||||||
|
/>
|
||||||
|
</StatisticsWrapper>
|
||||||
<TorrentCache cache={cache} cacheMap={cacheMap} />
|
<TorrentCache cache={cache} cacheMap={cacheMap} />
|
||||||
</DetailedTorrentCacheViewWrapper>
|
</DetailedTorrentCacheViewWrapper>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -91,20 +91,20 @@ export const SectionHeader = styled.div`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export const DetailedTorrentCacheViewWrapper = styled.div`
|
export const DetailedTorrentCacheViewWrapper = styled.div`
|
||||||
padding-top: 50px;
|
padding: 40px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
min-height: 80vh;
|
min-height: 80vh;
|
||||||
`
|
`
|
||||||
|
|
||||||
export const StatisticsWrapper = styled.div`
|
export const StatisticsWrapper = styled.div`
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(210px, min-content));
|
grid-template-columns: repeat(auto-fit, minmax(max-content, 220px));
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
`
|
`
|
||||||
|
|
||||||
export const StatisticsFieldWrapper = styled.div`
|
export const StatisticsFieldWrapper = styled.div`
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 40px max-content;
|
grid-template-columns: 40px 1fr;
|
||||||
grid-template-rows: min-content 50px;
|
grid-template-rows: min-content 50px;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
'title title'
|
'title title'
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable camelcase */
|
|
||||||
import 'fontsource-roboto'
|
import 'fontsource-roboto'
|
||||||
import { forwardRef, useState } from 'react'
|
import { forwardRef, useState } from 'react'
|
||||||
import HeightIcon from '@material-ui/icons/Height'
|
import HeightIcon from '@material-ui/icons/Height'
|
||||||
@@ -38,7 +37,7 @@ export default function Torrent({ torrent }) {
|
|||||||
const openDeleteTorrentAlert = () => setIsDeleteTorrentOpened(true)
|
const openDeleteTorrentAlert = () => setIsDeleteTorrentOpened(true)
|
||||||
const closeDeleteTorrentAlert = () => setIsDeleteTorrentOpened(false)
|
const closeDeleteTorrentAlert = () => setIsDeleteTorrentOpened(false)
|
||||||
|
|
||||||
const { title, name, poster, torrent_size, download_speed, hash } = torrent
|
const { title, name, poster, torrent_size: torrentSize, download_speed: downloadSpeed, hash } = torrent
|
||||||
|
|
||||||
const dropTorrent = () => axios.post(torrentsHost(), { action: 'drop', hash })
|
const dropTorrent = () => axios.post(torrentsHost(), { action: 'drop', hash })
|
||||||
const deleteTorrent = () => axios.post(torrentsHost(), { action: 'rem', hash })
|
const deleteTorrent = () => axios.post(torrentsHost(), { action: 'rem', hash })
|
||||||
@@ -77,14 +76,14 @@ export default function Torrent({ torrent }) {
|
|||||||
<span>
|
<span>
|
||||||
<TorrentCardDescriptionLabel>Size</TorrentCardDescriptionLabel>
|
<TorrentCardDescriptionLabel>Size</TorrentCardDescriptionLabel>
|
||||||
<TorrentCardDescriptionContent>
|
<TorrentCardDescriptionContent>
|
||||||
{torrent_size > 0 && humanizeSize(torrent_size)}
|
{torrentSize > 0 && humanizeSize(torrentSize)}
|
||||||
</TorrentCardDescriptionContent>
|
</TorrentCardDescriptionContent>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
<TorrentCardDescriptionLabel>Speed</TorrentCardDescriptionLabel>
|
<TorrentCardDescriptionLabel>Speed</TorrentCardDescriptionLabel>
|
||||||
<TorrentCardDescriptionContent>
|
<TorrentCardDescriptionContent>
|
||||||
{download_speed > 0 ? humanizeSize(download_speed) : '---'}
|
{downloadSpeed > 0 ? humanizeSize(downloadSpeed) : '---'}
|
||||||
</TorrentCardDescriptionContent>
|
</TorrentCardDescriptionContent>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user