mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
refactor. memory leak fix
This commit is contained in:
@@ -5,54 +5,63 @@ import DialogContent from '@material-ui/core/DialogContent'
|
|||||||
import { getPeerString, humanizeSize } from 'utils/Utils'
|
import { getPeerString, humanizeSize } from 'utils/Utils'
|
||||||
import { cacheHost } from 'utils/Hosts'
|
import { cacheHost } from 'utils/Hosts'
|
||||||
|
|
||||||
export default function DialogCacheInfo({ hash, open }) {
|
export default function DialogCacheInfo({ hash }) {
|
||||||
const [cache, setCache] = useState({})
|
const [cache, setCache] = useState({})
|
||||||
const timerID = useRef(-1)
|
|
||||||
const [pMap, setPMap] = useState([])
|
const [pMap, setPMap] = useState([])
|
||||||
|
const timerID = useRef(null)
|
||||||
|
const componentIsMounted = useRef(true)
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() => () => {
|
||||||
|
componentIsMounted.current = false
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hash)
|
if (hash) {
|
||||||
timerID.current = setInterval(() => {
|
timerID.current = setInterval(() => {
|
||||||
getCache(hash, cache => {
|
getCache(hash, value => {
|
||||||
setCache(cache)
|
// this is needed to avoid memory leak
|
||||||
|
if (componentIsMounted.current) setCache(value)
|
||||||
})
|
})
|
||||||
}, 100)
|
}, 100)
|
||||||
else clearInterval(timerID.current)
|
} else clearInterval(timerID.current)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(timerID.current)
|
clearInterval(timerID.current)
|
||||||
}
|
}
|
||||||
}, [hash, open])
|
}, [hash])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cache && cache.PiecesCount && cache.Pieces) {
|
if (!cache?.PiecesCount || !cache?.Pieces) return
|
||||||
const map = []
|
|
||||||
for (let i = 0; i < cache.PiecesCount; i++) {
|
|
||||||
const reader = 0
|
|
||||||
let cls = 'piece'
|
|
||||||
let prc = 0
|
|
||||||
if (cache.Pieces[i]) {
|
|
||||||
if (cache.Pieces[i].Completed && cache.Pieces[i].Size >= cache.Pieces[i].Length) cls += ' piece-complete'
|
|
||||||
else cls += ' piece-loading'
|
|
||||||
prc = ((cache.Pieces[i].Size / cache.Pieces[i].Length) * 100).toFixed(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.Readers.forEach(r => {
|
const { Pieces, PiecesCount, Readers } = cache
|
||||||
if (i >= r.Start && i <= r.End && i !== r.Reader) cls += ' reader-range'
|
|
||||||
if (i === r.Reader) {
|
const map = []
|
||||||
cls += ' piece-reader'
|
|
||||||
}
|
for (let i = 0; i < PiecesCount; i++) {
|
||||||
})
|
const cls = ['piece']
|
||||||
map.push({
|
let prc = 0
|
||||||
prc,
|
|
||||||
class: cls,
|
const currentPiece = Pieces[i]
|
||||||
info: i,
|
if (currentPiece) {
|
||||||
reader,
|
if (currentPiece.Completed && currentPiece.Size === currentPiece.Length) cls.push('piece-complete')
|
||||||
})
|
else cls.push('piece-loading')
|
||||||
|
|
||||||
|
prc = (currentPiece.Size / currentPiece.Length).toFixed(2)
|
||||||
}
|
}
|
||||||
setPMap(map)
|
|
||||||
|
Readers.forEach(r => {
|
||||||
|
if (i === r.Reader) return cls.push('piece-reader')
|
||||||
|
if (i >= r.Start && i <= r.End) cls.push('reader-range')
|
||||||
|
})
|
||||||
|
|
||||||
|
map.push({ prc, className: cls.join(' '), id: i })
|
||||||
}
|
}
|
||||||
}, [cache.Pieces])
|
|
||||||
|
setPMap(map)
|
||||||
|
}, [cache])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -84,20 +93,22 @@ export default function DialogCacheInfo({ hash, open }) {
|
|||||||
|
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<div className='cache'>
|
<div className='cache'>
|
||||||
{pMap.map(itm => (
|
{pMap.map(({ prc, className: currentPieceCalss, id }) => {
|
||||||
<span key={itm.info} className={itm.class} title={itm.info}>
|
const boxHeight = 12
|
||||||
{itm.prc > 0 && itm.prc < 100 && (
|
|
||||||
<div className='piece-progress' style={{ height: `${(itm.prc / 100) * 12}px` }} />
|
return (
|
||||||
)}
|
<span key={id} className={currentPieceCalss}>
|
||||||
</span>
|
{prc > 0 && prc < 1 && <div className='piece-progress' style={{ height: `${prc * boxHeight}px` }} />}
|
||||||
))}
|
</span>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCache(hash, callback) {
|
const getCache = (hash, callback) => {
|
||||||
try {
|
try {
|
||||||
fetch(cacheHost(), {
|
fetch(cacheHost(), {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@@ -108,15 +119,10 @@ function getCache(hash, callback) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(
|
.then(callback, error => {
|
||||||
json => {
|
callback({})
|
||||||
callback(json)
|
console.error(error)
|
||||||
},
|
})
|
||||||
error => {
|
|
||||||
callback({})
|
|
||||||
console.error(error)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
callback({})
|
callback({})
|
||||||
|
|||||||
@@ -123,10 +123,10 @@ export default function Torrent({ torrent }) {
|
|||||||
</TorrentCard>
|
</TorrentCard>
|
||||||
|
|
||||||
<Dialog open={open} onClose={() => setOpen(false)} aria-labelledby='form-dialog-title' fullWidth maxWidth='lg'>
|
<Dialog open={open} onClose={() => setOpen(false)} aria-labelledby='form-dialog-title' fullWidth maxWidth='lg'>
|
||||||
{!showCache ? (
|
{showCache ? (
|
||||||
<DialogTorrentInfo torrent={(open, torrentLocalComponentValue)} />
|
<DialogCacheInfo hash={torrentLocalComponentValue.hash} />
|
||||||
) : (
|
) : (
|
||||||
<DialogCacheInfo hash={(open, torrentLocalComponentValue.hash)} />
|
<DialogTorrentInfo torrent={torrentLocalComponentValue} />
|
||||||
)}
|
)}
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button variant='outlined' color='primary' onClick={() => setOpen(false)}>
|
<Button variant='outlined' color='primary' onClick={() => setOpen(false)}>
|
||||||
|
|||||||
Reference in New Issue
Block a user