Files
TorrServerJellyfin/web/src/components/DialogTorrentDetailsContent/TorrentCache.jsx
2021-06-03 13:21:38 +03:00

124 lines
5.2 KiB
JavaScript

import { memo, useEffect, useState } from 'react'
import DialogContent from '@material-ui/core/DialogContent'
import { Stage, Layer } from 'react-konva'
import Measure from 'react-measure'
import isEqual from 'lodash/isEqual'
import { v4 as uuidv4 } from 'uuid'
import SingleBlock from './SingleBlock'
import { useCreateCacheMap } from './customHooks'
const TorrentCache = memo(
({ cache, isMini }) => {
const [dimensions, setDimensions] = useState({ width: 0, height: 0 })
const [stageSettings, setStageSettings] = useState({
boxHeight: null,
strokeWidth: null,
marginBetweenBlocks: null,
stageOffset: null,
})
const cacheMap = useCreateCacheMap(cache)
const updateStageSettings = (boxHeight, strokeWidth) => {
setStageSettings({
boxHeight,
strokeWidth,
marginBetweenBlocks: strokeWidth,
stageOffset: strokeWidth * 2,
})
}
useEffect(() => {
// initializing stageSettings
if (isMini) return dimensions.width < 500 ? updateStageSettings(20, 3) : updateStageSettings(24, 4)
updateStageSettings(12, 2)
}, [isMini, dimensions.width])
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 || 0
const amountOfRows = Math.ceil((isMini ? amountOfBlocksToRenderInShortView : cacheMap.length) / piecesInOneRow)
const activeId = null
const cacheMapWithoutEmptyBlocks = cacheMap.filter(({ isComplete, inProgress }) => inProgress || isComplete)
const extraEmptyBlocksForFillingLine =
cacheMapWithoutEmptyBlocks.length < amountOfBlocksToRenderInShortView
? new Array(amountOfBlocksToRenderInShortView - cacheMapWithoutEmptyBlocks.length + 1).fill({})
: []
const shortCacheMap = [...cacheMapWithoutEmptyBlocks, ...extraEmptyBlocksForFillingLine]
return (
<Measure bounds onResize={({ bounds }) => setDimensions(bounds)}>
{({ measureRef }) => (
<div ref={measureRef}>
<DialogContent
{...(isMini
? { style: { padding: 0, maxHeight: '340px', overflow: 'auto' } }
: { style: { padding: 0 } })}
>
<Stage
style={{ display: 'flex', justifyContent: 'center' }}
offset={{ x: -stageOffset, y: -stageOffset }}
width={stageOffset + blockSizeWithMargin * piecesInOneRow || 0}
height={stageOffset + blockSizeWithMargin * amountOfRows || 0}
>
<Layer>
{isMini
? shortCacheMap.map(({ percentage, isComplete, inProgress, isActive, isReaderRange }, i) => {
const currentRow = Math.floor(i / piecesInOneRow)
const shouldBeRendered = inProgress || isComplete || i <= amountOfBlocksToRenderInShortView
return (
shouldBeRendered && (
<SingleBlock
key={uuidv4()}
x={(i % piecesInOneRow) * blockSizeWithMargin}
y={currentRow * blockSizeWithMargin}
percentage={percentage}
inProgress={inProgress}
isComplete={isComplete}
isReaderRange={isReaderRange}
isActive={isActive}
boxHeight={boxHeight}
strokeWidth={strokeWidth}
/>
)
)
})
: cacheMap.map(({ id, percentage, isComplete, inProgress, isActive, isReaderRange }) => {
const currentRow = Math.floor((isMini ? id - activeId : id) / piecesInOneRow)
return (
<SingleBlock
key={uuidv4()}
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>
)
},
(prev, next) => isEqual(prev.cache.Pieces, next.cache.Pieces) && isEqual(prev.cache.Readers, next.cache.Readers),
)
export default TorrentCache