Fix downloads

This commit is contained in:
Geomitron
2023-12-25 02:49:46 -06:00
parent ba309654ca
commit 99cfb306be
30 changed files with 557 additions and 1450 deletions

View File

@@ -1,51 +1,110 @@
import Comparators, { Comparator } from 'comparators'
import { emitIpcEvent } from '../../main'
import { ChartDownload } from './ChartDownload'
export class DownloadQueue {
private downloadQueue: ChartDownload[] = []
private retryQueue: ChartDownload[] = []
private erroredQueue: ChartDownload[] = []
isDownloadingLink(filesHash: string) {
return this.downloadQueue.some(download => download.hash === filesHash)
private downloadRunning = false
private isChartInQueue(md5: string) {
if (this.downloadQueue.find(cd => cd.md5 === md5)) { return true }
if (this.retryQueue.find(cd => cd.md5 === md5)) { return true }
if (this.erroredQueue.find(cd => cd.md5 === md5)) { return true }
return false
}
isEmpty() {
return this.downloadQueue.length === 0
}
add(md5: string, chartName: string) {
if (!this.isChartInQueue(md5)) {
const chartDownload = new ChartDownload(md5, chartName)
this.downloadQueue.push(chartDownload)
push(chartDownload: ChartDownload) {
this.downloadQueue.push(chartDownload)
this.sort()
}
chartDownload.on('progress', (message, percent) => emitIpcEvent('downloadQueueUpdate', {
md5,
chartName,
header: message.header,
body: message.body,
percent,
type: 'good',
isPath: false,
}))
chartDownload.on('error', err => {
emitIpcEvent('downloadQueueUpdate', {
md5,
chartName,
header: err.header,
body: err.body,
percent: null,
type: 'error',
isPath: err.isPath ?? false,
})
shift() {
return this.downloadQueue.shift()
}
this.downloadQueue = this.downloadQueue.filter(cd => cd !== chartDownload)
this.erroredQueue.push(chartDownload)
this.downloadRunning = false
this.moveQueue()
})
chartDownload.on('end', destinationPath => {
emitIpcEvent('downloadQueueUpdate', {
md5,
chartName,
header: 'Download complete',
body: destinationPath,
percent: 100,
type: 'done',
isPath: true,
})
get(versionID: number) {
return this.downloadQueue.find(download => download.versionID === versionID)
}
this.downloadQueue = this.downloadQueue.filter(cd => cd !== chartDownload)
this.downloadRunning = false
this.moveQueue()
})
remove(versionID: number) {
const index = this.downloadQueue.findIndex(download => download.versionID === versionID)
if (index !== -1) {
this.downloadQueue[index].cancel()
this.downloadQueue.splice(index, 1)
emitIpcEvent('queueUpdated', this.downloadQueue.map(download => download.versionID))
this.moveQueue()
}
}
private sort() {
let comparator: Comparator<unknown> | undefined = Comparators.comparing('allFilesProgress', { reversed: true })
remove(md5: string) {
if (this.downloadQueue[0]?.md5 === md5) {
this.downloadQueue[0].cancel()
this.downloadRunning = false
}
this.downloadQueue = this.downloadQueue.filter(cd => cd.md5 !== md5)
this.retryQueue = this.retryQueue.filter(cd => cd.md5 !== md5)
this.erroredQueue = this.erroredQueue.filter(cd => cd.md5 !== md5)
const prioritizeArchives = true
if (prioritizeArchives) {
comparator = comparator.thenComparing?.('isArchive', { reversed: true }) || undefined
emitIpcEvent('downloadQueueUpdate', {
md5,
chartName: 'Canceled',
header: '',
body: '',
percent: null,
type: 'cancel',
isPath: false,
})
}
retry(md5: string) {
const erroredChartDownload = this.erroredQueue.find(cd => cd.md5 === md5)
if (erroredChartDownload) {
this.erroredQueue = this.erroredQueue.filter(cd => cd.md5 !== md5)
this.retryQueue.push(erroredChartDownload)
}
this.downloadQueue.sort(comparator)
emitIpcEvent('queueUpdated', this.downloadQueue.map(download => download.versionID))
this.moveQueue()
}
private moveQueue() {
if (!this.downloadRunning) {
if (this.retryQueue.length) {
this.downloadQueue.unshift(this.retryQueue.shift()!)
}
if (this.downloadQueue.length) {
this.downloadRunning = true
this.downloadQueue[0].startOrRetry()
}
}
}
}