Files
Cultivation/src/utils/download.ts
2022-05-11 21:18:07 -07:00

87 lines
2.4 KiB
TypeScript

import { invoke } from '@tauri-apps/api/tauri'
import { listen } from '@tauri-apps/api/event'
export default class DownloadHandler {
downloads: {
path: string,
progress: number,
total: number,
status: string,
error?: string,
}[]
// Pass tauri invoke function
constructor() {
this.downloads = []
listen('download_progress', (...payload) => {
// @ts-expect-error Payload may be unknown but backend always returns this object
const obj: {
downloaded: string,
total: string,
path: string,
} = payload[0].payload
const index = this.downloads.findIndex(download => download.path === obj.path)
this.downloads[index].progress = parseInt(obj.downloaded, 10)
this.downloads[index].total = parseInt(obj.total, 10)
})
listen('download_finished', (...payload) => {
// Remove from array
const filename = payload[0]?.payload
// set status to finished
const index = this.downloads.findIndex(download => download.path === filename)
this.downloads[index].status = 'finished'
})
listen('download_error', (...payload) => {
// @ts-expect-error shut up typescript
const errorData: {
path: string,
error: string,
} = payload[0]?.payload
// Set download to error
const index = this.downloads.findIndex(download => download.path === errorData.path)
this.downloads[index].status = 'error'
this.downloads[index].error = errorData.error
})
}
getDownloads() {
return this.downloads
}
addDownload(url: string, path: string) {
// Begin download from rust backend, don't add if the download addition fails
invoke('download_file', { url, path })
const obj = {
path,
progress: 0,
total: 0,
status: 'downloading'
}
this.downloads.push(obj)
}
getDownloadProgress(path: string) {
const index = this.downloads.findIndex(download => download.path === path)
return this.downloads[index] || null
}
getTotalAverage() {
const files = this.downloads.filter(d => d.status !== 'finished')
const total = files.reduce((acc, d) => acc + d.total, 0)
const progress = files.reduce((acc, d) => acc + d.progress, 0)
return {
average: (progress / total) * 100 || 0,
files: this.downloads.filter(d => d.status !== 'finished').length,
totalSize: total,
}
}
}