mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 13:36:09 +05:00
124 lines
5.2 KiB
JavaScript
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
|