refactor. memory leak fix

This commit is contained in:
Daniel Shleifman
2021-05-26 14:02:18 +03:00
parent 75a538fed6
commit 0e753c56da
2 changed files with 58 additions and 52 deletions

View File

@@ -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({})

View File

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