added more widgets

This commit is contained in:
Daniel Shleifman
2021-05-31 17:03:57 +03:00
parent f377046e94
commit 34ff7c5d53
5 changed files with 66 additions and 238 deletions

View File

@@ -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,
],
})}
/>
)
}

View File

@@ -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
}
}
}
*/

View File

@@ -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>
) : ( ) : (

View File

@@ -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'

View File

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