mirror of
https://github.com/Myxelium/Bridge-Multi.git
synced 2026-04-11 22:29:38 +00:00
Restructure; use DaisyUI
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import { parse } from 'path'
|
||||
import { rimraf } from 'rimraf'
|
||||
|
||||
import { NewDownload, ProgressType } from 'src/electron/shared/interfaces/download.interface'
|
||||
import { DriveFile } from 'src/electron/shared/interfaces/songDetails.interface'
|
||||
import { emitIPCEvent } from '../../main'
|
||||
import { hasVideoExtension } from '../../shared/ElectronUtilFunctions'
|
||||
import { sanitizeFilename } from '../../shared/UtilFunctions'
|
||||
import { getSettings } from '../SettingsHandler.ipc'
|
||||
import { NewDownload, ProgressType } from '../../../src-shared/interfaces/download.interface'
|
||||
import { DriveFile } from '../../../src-shared/interfaces/songDetails.interface'
|
||||
import { sanitizeFilename } from '../../../src-shared/UtilFunctions'
|
||||
import { hasVideoExtension } from '../../ElectronUtilFunctions'
|
||||
import { emitIpcEvent } from '../../main'
|
||||
import { settings } from '../SettingsHandler.ipc'
|
||||
// import { FileDownloader, getDownloader } from './FileDownloader'
|
||||
import { FilesystemChecker } from './FilesystemChecker'
|
||||
import { FileTransfer } from './FileTransfer'
|
||||
@@ -22,8 +22,8 @@ export interface DownloadError { header: string; body: string; isLink?: boolean
|
||||
|
||||
export class ChartDownload {
|
||||
|
||||
private retryFn: () => void | Promise<void>
|
||||
private cancelFn: () => void
|
||||
private retryFn: undefined | (() => void | Promise<void>)
|
||||
private cancelFn: undefined | (() => void)
|
||||
|
||||
private callbacks = {} as Callbacks
|
||||
private files: DriveFile[]
|
||||
@@ -62,7 +62,7 @@ export class ChartDownload {
|
||||
|
||||
filterDownloadFiles(files: DriveFile[]) {
|
||||
return files.filter(file => {
|
||||
return (file.name != 'ch.dat') && (getSettings().downloadVideos || !hasVideoExtension(file.name))
|
||||
return (file.name !== 'ch.dat') && (settings.downloadVideos || !hasVideoExtension(file.name))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ export class ChartDownload {
|
||||
* Retries the last failed step if it is running.
|
||||
*/
|
||||
retry() { // Only allow it to be called once
|
||||
if (this.retryFn != undefined) {
|
||||
if (this.retryFn !== undefined) {
|
||||
this._hasFailed = false
|
||||
const retryFn = this.retryFn
|
||||
this.retryFn = undefined
|
||||
@@ -89,7 +89,7 @@ export class ChartDownload {
|
||||
* Cancels the download if it is running.
|
||||
*/
|
||||
cancel() { // Only allow it to be called once
|
||||
if (this.cancelFn != undefined) {
|
||||
if (this.cancelFn !== undefined) {
|
||||
const cancelFn = this.cancelFn
|
||||
this.cancelFn = undefined
|
||||
cancelFn()
|
||||
@@ -105,7 +105,7 @@ export class ChartDownload {
|
||||
private updateGUI(header: string, description: string, type: ProgressType, isLink = false) {
|
||||
if (this.wasCanceled) { return }
|
||||
|
||||
emitIPCEvent('download-updated', {
|
||||
emitIpcEvent('downloadUpdated', {
|
||||
versionID: this.versionID,
|
||||
title: `${this.data.chartName} - ${this.data.artist}`,
|
||||
header: header,
|
||||
@@ -122,7 +122,7 @@ export class ChartDownload {
|
||||
private handleError(err: DownloadError, retry: () => void) {
|
||||
this._hasFailed = true
|
||||
this.retryFn = retry
|
||||
this.updateGUI(err.header, err.body, 'error', err.isLink == true)
|
||||
this.updateGUI(err.header, err.body, 'error', err.isLink === true)
|
||||
this.callbacks.error()
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ export class ChartDownload {
|
||||
|
||||
// extractor.on('extractProgress', (percent, filecount) => {
|
||||
// this.percent = interpolate(percent, 0, 100, 80, 95)
|
||||
// this.updateGUI(`[${archive}] (${filecount} file${filecount == 1 ? '' : 's'} extracted)`, `Extracting... (${percent}%)`, 'good')
|
||||
// this.updateGUI(`[${archive}] (${filecount} file${filecount === 1 ? '' : 's'} extracted)`, `Extracting... (${percent}%)`, 'good')
|
||||
// })
|
||||
|
||||
// extractor.on('error', this.handleError.bind(this))
|
||||
|
||||
@@ -1,86 +1,82 @@
|
||||
import { Download } from '../../shared/interfaces/download.interface'
|
||||
import { IPCEmitHandler } from '../../shared/IPCHandler'
|
||||
import { Download } from '../../../src-shared/interfaces/download.interface'
|
||||
import { ChartDownload } from './ChartDownload'
|
||||
import { DownloadQueue } from './DownloadQueue'
|
||||
|
||||
class DownloadHandler implements IPCEmitHandler<'download'> {
|
||||
event = 'download' as const
|
||||
const downloadQueue: DownloadQueue = new DownloadQueue()
|
||||
const retryWaiting: ChartDownload[] = []
|
||||
|
||||
downloadQueue: DownloadQueue = new DownloadQueue()
|
||||
currentDownload: ChartDownload = undefined
|
||||
retryWaiting: ChartDownload[] = []
|
||||
let currentDownload: ChartDownload | undefined = undefined
|
||||
|
||||
handler(data: Download) {
|
||||
switch (data.action) {
|
||||
case 'add': this.addDownload(data); break
|
||||
case 'retry': this.retryDownload(data); break
|
||||
case 'cancel': this.cancelDownload(data); break
|
||||
}
|
||||
export async function download(data: Download) {
|
||||
switch (data.action) {
|
||||
case 'add': addDownload(data); break
|
||||
case 'retry': retryDownload(data); break
|
||||
case 'cancel': cancelDownload(data); break
|
||||
}
|
||||
}
|
||||
|
||||
function addDownload(data: Download) {
|
||||
const filesHash = data.data!.driveData.filesHash // Note: using versionID would cause chart packs to download multiple times
|
||||
if (currentDownload?.hash === filesHash || downloadQueue.isDownloadingLink(filesHash)) {
|
||||
return
|
||||
}
|
||||
|
||||
private addDownload(data: Download) {
|
||||
const filesHash = data.data.driveData.filesHash // Note: using versionID would cause chart packs to download multiple times
|
||||
if (this.currentDownload?.hash == filesHash || this.downloadQueue.isDownloadingLink(filesHash)) {
|
||||
return
|
||||
}
|
||||
const newDownload = new ChartDownload(data.versionID, data.data!)
|
||||
addDownloadEventListeners(newDownload)
|
||||
if (currentDownload === undefined) {
|
||||
currentDownload = newDownload
|
||||
newDownload.beginDownload()
|
||||
} else {
|
||||
downloadQueue.push(newDownload)
|
||||
}
|
||||
}
|
||||
|
||||
const newDownload = new ChartDownload(data.versionID, data.data)
|
||||
this.addDownloadEventListeners(newDownload)
|
||||
if (this.currentDownload == undefined) {
|
||||
this.currentDownload = newDownload
|
||||
newDownload.beginDownload()
|
||||
function retryDownload(data: Download) {
|
||||
const index = retryWaiting.findIndex(download => download.versionID === data.versionID)
|
||||
if (index !== -1) {
|
||||
const retryDownload = retryWaiting.splice(index, 1)[0]
|
||||
retryDownload.displayRetrying()
|
||||
if (currentDownload === undefined) {
|
||||
currentDownload = retryDownload
|
||||
retryDownload.retry()
|
||||
} else {
|
||||
this.downloadQueue.push(newDownload)
|
||||
}
|
||||
}
|
||||
|
||||
private retryDownload(data: Download) {
|
||||
const index = this.retryWaiting.findIndex(download => download.versionID == data.versionID)
|
||||
if (index != -1) {
|
||||
const retryDownload = this.retryWaiting.splice(index, 1)[0]
|
||||
retryDownload.displayRetrying()
|
||||
if (this.currentDownload == undefined) {
|
||||
this.currentDownload = retryDownload
|
||||
retryDownload.retry()
|
||||
} else {
|
||||
this.downloadQueue.push(retryDownload)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private cancelDownload(data: Download) {
|
||||
if (this.currentDownload?.versionID == data.versionID) {
|
||||
this.currentDownload.cancel()
|
||||
this.currentDownload = undefined
|
||||
this.startNextDownload()
|
||||
} else {
|
||||
this.downloadQueue.remove(data.versionID)
|
||||
}
|
||||
}
|
||||
|
||||
private addDownloadEventListeners(download: ChartDownload) {
|
||||
download.on('complete', () => {
|
||||
this.currentDownload = undefined
|
||||
this.startNextDownload()
|
||||
})
|
||||
|
||||
download.on('error', () => {
|
||||
this.retryWaiting.push(this.currentDownload)
|
||||
this.currentDownload = undefined
|
||||
this.startNextDownload()
|
||||
})
|
||||
}
|
||||
|
||||
private startNextDownload() {
|
||||
if (!this.downloadQueue.isEmpty()) {
|
||||
this.currentDownload = this.downloadQueue.shift()
|
||||
if (this.currentDownload.hasFailed) {
|
||||
this.currentDownload.retry()
|
||||
} else {
|
||||
this.currentDownload.beginDownload()
|
||||
}
|
||||
downloadQueue.push(retryDownload)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const downloadHandler = new DownloadHandler()
|
||||
function cancelDownload(data: Download) {
|
||||
if (currentDownload?.versionID === data.versionID) {
|
||||
currentDownload.cancel()
|
||||
currentDownload = undefined
|
||||
startNextDownload()
|
||||
} else {
|
||||
downloadQueue.remove(data.versionID)
|
||||
}
|
||||
}
|
||||
|
||||
function addDownloadEventListeners(download: ChartDownload) {
|
||||
download.on('complete', () => {
|
||||
currentDownload = undefined
|
||||
startNextDownload()
|
||||
})
|
||||
|
||||
download.on('error', () => {
|
||||
if (currentDownload) {
|
||||
retryWaiting.push(currentDownload)
|
||||
currentDownload = undefined
|
||||
}
|
||||
startNextDownload()
|
||||
})
|
||||
}
|
||||
|
||||
function startNextDownload() {
|
||||
currentDownload = downloadQueue.shift()
|
||||
if (currentDownload) {
|
||||
if (currentDownload.hasFailed) {
|
||||
currentDownload.retry()
|
||||
} else {
|
||||
currentDownload.beginDownload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Comparators from 'comparators'
|
||||
import Comparators, { Comparator } from 'comparators'
|
||||
|
||||
import { emitIPCEvent } from '../../main'
|
||||
import { emitIpcEvent } from '../../main'
|
||||
import { ChartDownload } from './ChartDownload'
|
||||
|
||||
export class DownloadQueue {
|
||||
@@ -8,11 +8,11 @@ export class DownloadQueue {
|
||||
private downloadQueue: ChartDownload[] = []
|
||||
|
||||
isDownloadingLink(filesHash: string) {
|
||||
return this.downloadQueue.some(download => download.hash == filesHash)
|
||||
return this.downloadQueue.some(download => download.hash === filesHash)
|
||||
}
|
||||
|
||||
isEmpty() {
|
||||
return this.downloadQueue.length == 0
|
||||
return this.downloadQueue.length === 0
|
||||
}
|
||||
|
||||
push(chartDownload: ChartDownload) {
|
||||
@@ -25,27 +25,27 @@ export class DownloadQueue {
|
||||
}
|
||||
|
||||
get(versionID: number) {
|
||||
return this.downloadQueue.find(download => download.versionID == versionID)
|
||||
return this.downloadQueue.find(download => download.versionID === versionID)
|
||||
}
|
||||
|
||||
remove(versionID: number) {
|
||||
const index = this.downloadQueue.findIndex(download => download.versionID == versionID)
|
||||
if (index != -1) {
|
||||
const index = this.downloadQueue.findIndex(download => download.versionID === versionID)
|
||||
if (index !== -1) {
|
||||
this.downloadQueue[index].cancel()
|
||||
this.downloadQueue.splice(index, 1)
|
||||
emitIPCEvent('queue-updated', this.downloadQueue.map(download => download.versionID))
|
||||
emitIpcEvent('queueUpdated', this.downloadQueue.map(download => download.versionID))
|
||||
}
|
||||
}
|
||||
|
||||
private sort() {
|
||||
let comparator = Comparators.comparing('allFilesProgress', { reversed: true })
|
||||
let comparator: Comparator<unknown> | undefined = Comparators.comparing('allFilesProgress', { reversed: true })
|
||||
|
||||
const prioritizeArchives = true
|
||||
if (prioritizeArchives) {
|
||||
comparator = comparator.thenComparing('isArchive', { reversed: true })
|
||||
comparator = comparator.thenComparing?.('isArchive', { reversed: true }) || undefined
|
||||
}
|
||||
|
||||
this.downloadQueue.sort(comparator)
|
||||
emitIPCEvent('queue-updated', this.downloadQueue.map(download => download.versionID))
|
||||
emitIpcEvent('queueUpdated', this.downloadQueue.map(download => download.versionID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
// }))
|
||||
|
||||
// this.req.on('header', this.cancelable((statusCode, headers: Headers) => {
|
||||
// if (statusCode != 200) {
|
||||
// if (statusCode !== 200) {
|
||||
// this.failDownload(downloadErrors.responseError(statusCode))
|
||||
// return
|
||||
// }
|
||||
@@ -246,7 +246,7 @@
|
||||
// * Download the file after waiting for the google rate limit.
|
||||
// */
|
||||
// beginDownload() {
|
||||
// if (this.fileID == undefined) {
|
||||
// if (this.fileID === undefined) {
|
||||
// this.failDownload(downloadErrors.linkError(this.url))
|
||||
// }
|
||||
|
||||
|
||||
@@ -52,11 +52,11 @@
|
||||
// readdir(this.sourceFolder, (err, files) => {
|
||||
// if (err) {
|
||||
// this.callbacks.error(extractErrors.readError(err), () => this.beginExtract())
|
||||
// } else if (files.length == 0) {
|
||||
// } else if (files.length === 0) {
|
||||
// this.callbacks.error(extractErrors.emptyError(), () => this.beginExtract())
|
||||
// } else {
|
||||
// this.callbacks.start(files[0])
|
||||
// this.extract(join(this.sourceFolder, files[0]), extname(files[0]) == '.rar')
|
||||
// this.extract(join(this.sourceFolder, files[0]), extname(files[0]) === '.rar')
|
||||
// }
|
||||
// })
|
||||
// }), 100) // Wait for filesystem to process downloaded file
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
// const fileList = extractor.getFileList()
|
||||
|
||||
// if (fileList[0].state != 'FAIL') {
|
||||
// if (fileList[0].state !== 'FAIL') {
|
||||
|
||||
// // Create directories for nested archives (because unrarjs didn't feel like handling that automatically)
|
||||
// const headers = fileList[1].fileHeaders
|
||||
@@ -93,7 +93,7 @@
|
||||
// } catch (err) {
|
||||
// this.callbacks.error(
|
||||
// extractErrors.rarmkdirError(err, fullPath),
|
||||
// () => this.extract(fullPath, extname(fullPath) == '.rar'),
|
||||
// () => this.extract(fullPath, extname(fullPath) === '.rar'),
|
||||
// )
|
||||
// return
|
||||
// }
|
||||
@@ -103,10 +103,10 @@
|
||||
|
||||
// const extractResult = extractor.extractAll()
|
||||
|
||||
// if (extractResult[0].state == 'FAIL') {
|
||||
// if (extractResult[0].state === 'FAIL') {
|
||||
// this.callbacks.error(
|
||||
// extractErrors.rarextractError(extractResult[0], fullPath),
|
||||
// () => this.extract(fullPath, extname(fullPath) == '.rar'),
|
||||
// () => this.extract(fullPath, extname(fullPath) === '.rar'),
|
||||
// )
|
||||
// } else {
|
||||
// this.deleteArchive(fullPath)
|
||||
@@ -143,7 +143,7 @@
|
||||
// */
|
||||
// private deleteArchive(fullPath: string) {
|
||||
// unlink(fullPath, this.cancelable(err => {
|
||||
// if (err && err.code != 'ENOENT') {
|
||||
// if (err && err.code !== 'ENOENT') {
|
||||
// devLog(`Warning: failed to delete archive at [${fullPath}]`)
|
||||
// }
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { join } from 'path'
|
||||
import { rimraf } from 'rimraf'
|
||||
import { promisify } from 'util'
|
||||
|
||||
import { getSettings } from '../SettingsHandler.ipc'
|
||||
import { settings } from '../SettingsHandler.ipc'
|
||||
import { DownloadError } from './ChartDownload'
|
||||
|
||||
const readdir = promisify(_readdir)
|
||||
@@ -17,12 +17,13 @@ interface EventCallback {
|
||||
type Callbacks = { [E in keyof EventCallback]: EventCallback[E] }
|
||||
|
||||
const transferErrors = {
|
||||
libraryError: () => ({ header: 'Library folder not specified', body: 'Please go to the settings to set your library folder.' }),
|
||||
readError: (err: NodeJS.ErrnoException) => fsError(err, 'Failed to read file.'),
|
||||
deleteError: (err: NodeJS.ErrnoException) => fsError(err, 'Failed to delete file.'),
|
||||
rimrafError: (err: NodeJS.ErrnoException) => fsError(err, 'Failed to delete folder.'),
|
||||
mvError: (err: NodeJS.ErrnoException) => fsError(
|
||||
err,
|
||||
`Failed to move folder to library.${err.code == 'EPERM' ? ' (does the chart already exist?)' : ''}`,
|
||||
`Failed to move folder to library.${err.code === 'EPERM' ? ' (does the chart already exist?)' : ''}`,
|
||||
),
|
||||
}
|
||||
|
||||
@@ -34,10 +35,10 @@ export class FileTransfer {
|
||||
|
||||
private callbacks = {} as Callbacks
|
||||
private wasCanceled = false
|
||||
private destinationFolder: string
|
||||
private destinationFolder: string | null
|
||||
private nestedSourceFolder: string // The top-level folder that is copied to the library folder
|
||||
constructor(private sourceFolder: string, destinationFolderName: string) {
|
||||
this.destinationFolder = join(getSettings().libraryPath, destinationFolderName)
|
||||
this.destinationFolder = settings.libraryPath ? join(settings.libraryPath, destinationFolderName) : null
|
||||
this.nestedSourceFolder = sourceFolder
|
||||
}
|
||||
|
||||
@@ -49,10 +50,14 @@ export class FileTransfer {
|
||||
}
|
||||
|
||||
async beginTransfer() {
|
||||
this.callbacks.start(this.destinationFolder)
|
||||
await this.cleanFolder()
|
||||
if (this.wasCanceled) { return }
|
||||
this.moveFolder()
|
||||
if (!this.destinationFolder) {
|
||||
this.callbacks.error(transferErrors.libraryError(), () => this.beginTransfer())
|
||||
} else {
|
||||
this.callbacks.start(this.destinationFolder)
|
||||
await this.cleanFolder()
|
||||
if (this.wasCanceled) { return }
|
||||
this.moveFolder()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,7 +73,7 @@ export class FileTransfer {
|
||||
}
|
||||
|
||||
// Remove nested folders
|
||||
if (files.length == 1 && !files[0].isFile()) {
|
||||
if (files.length === 1 && !files[0].isFile()) {
|
||||
this.nestedSourceFolder = join(this.nestedSourceFolder, files[0].name)
|
||||
await this.cleanFolder()
|
||||
return
|
||||
@@ -76,7 +81,7 @@ export class FileTransfer {
|
||||
|
||||
// Delete '__MACOSX' folder
|
||||
for (const file of files) {
|
||||
if (!file.isFile() && file.name == '__MACOSX') {
|
||||
if (!file.isFile() && file.name === '__MACOSX') {
|
||||
try {
|
||||
await rimraf(join(this.nestedSourceFolder, file.name))
|
||||
} catch (err) {
|
||||
@@ -93,14 +98,18 @@ export class FileTransfer {
|
||||
* Moves the downloaded chart to the library path.
|
||||
*/
|
||||
private moveFolder() {
|
||||
mv(this.nestedSourceFolder, this.destinationFolder, { mkdirp: true }, err => {
|
||||
if (err) {
|
||||
this.callbacks.error(transferErrors.mvError(err), () => this.moveFolder())
|
||||
} else {
|
||||
rimraf(this.sourceFolder) // Delete temp folder
|
||||
this.callbacks.complete()
|
||||
}
|
||||
})
|
||||
if (!this.destinationFolder) {
|
||||
this.callbacks.error(transferErrors.libraryError(), () => this.moveFolder())
|
||||
} else {
|
||||
mv(this.nestedSourceFolder, this.destinationFolder, { mkdirp: true }, err => {
|
||||
if (err) {
|
||||
this.callbacks.error(transferErrors.mvError(err), () => this.moveFolder())
|
||||
} else {
|
||||
rimraf(this.sourceFolder) // Delete temp folder
|
||||
this.callbacks.complete()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import { randomBytes as _randomBytes } from 'crypto'
|
||||
import { access, constants, mkdir } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { promisify } from 'util'
|
||||
|
||||
import { devLog } from '../../shared/ElectronUtilFunctions'
|
||||
import { tempPath } from '../../shared/Paths'
|
||||
import { AnyFunction } from '../../shared/UtilFunctions'
|
||||
import { getSettings } from '../SettingsHandler.ipc'
|
||||
import { tempPath } from '../../../src-shared/Paths'
|
||||
import { AnyFunction } from '../../../src-shared/UtilFunctions'
|
||||
import { devLog } from '../../ElectronUtilFunctions'
|
||||
import { settings } from '../SettingsHandler.ipc'
|
||||
import { DownloadError } from './ChartDownload'
|
||||
|
||||
const randomBytes = promisify(_randomBytes)
|
||||
|
||||
interface EventCallback {
|
||||
'start': () => void
|
||||
'error': (err: DownloadError, retry: () => void | Promise<void>) => void
|
||||
@@ -19,7 +15,7 @@ interface EventCallback {
|
||||
type Callbacks = { [E in keyof EventCallback]: EventCallback[E] }
|
||||
|
||||
const filesystemErrors = {
|
||||
libraryFolder: () => ({ header: 'Library folder not specified', body: 'Please go to the settings to set your library folder.' }),
|
||||
libraryError: () => ({ header: 'Library folder not specified', body: 'Please go to the settings to set your library folder.' }),
|
||||
libraryAccess: (err: NodeJS.ErrnoException) => fsError(err, 'Failed to access library folder.'),
|
||||
destinationFolderExists: (destinationPath: string) => {
|
||||
return { header: 'This chart already exists in your library folder.', body: destinationPath, isLink: true }
|
||||
@@ -56,10 +52,10 @@ export class FilesystemChecker {
|
||||
* Verifies that the user has specified a library folder.
|
||||
*/
|
||||
private checkLibraryFolder() {
|
||||
if (getSettings().libraryPath == undefined) {
|
||||
this.callbacks.error(filesystemErrors.libraryFolder(), () => this.beginCheck())
|
||||
if (settings.libraryPath === undefined) {
|
||||
this.callbacks.error(filesystemErrors.libraryError(), () => this.beginCheck())
|
||||
} else {
|
||||
access(getSettings().libraryPath, constants.W_OK, this.cancelable(err => {
|
||||
access(settings.libraryPath, constants.W_OK, this.cancelable(err => {
|
||||
if (err) {
|
||||
this.callbacks.error(filesystemErrors.libraryAccess(err), () => this.beginCheck())
|
||||
} else {
|
||||
@@ -73,21 +69,25 @@ export class FilesystemChecker {
|
||||
* Checks that the destination folder doesn't already exist.
|
||||
*/
|
||||
private checkDestinationFolder() {
|
||||
const destinationPath = join(getSettings().libraryPath, this.destinationFolderName)
|
||||
access(destinationPath, constants.F_OK, this.cancelable(err => {
|
||||
if (err) { // File does not exist
|
||||
this.createDownloadFolder()
|
||||
} else {
|
||||
this.callbacks.error(filesystemErrors.destinationFolderExists(destinationPath), () => this.beginCheck())
|
||||
}
|
||||
}))
|
||||
if (!settings.libraryPath) {
|
||||
this.callbacks.error(filesystemErrors.libraryError(), () => this.beginCheck())
|
||||
} else {
|
||||
const destinationPath = join(settings.libraryPath, this.destinationFolderName)
|
||||
access(destinationPath, constants.F_OK, this.cancelable(err => {
|
||||
if (err) { // File does not exist
|
||||
this.createDownloadFolder()
|
||||
} else {
|
||||
this.callbacks.error(filesystemErrors.destinationFolderExists(destinationPath), () => this.beginCheck())
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to create a unique folder in Bridge's data paths.
|
||||
*/
|
||||
private async createDownloadFolder(retryCount = 0) {
|
||||
const tempChartPath = join(tempPath, `chart_${(await randomBytes(5)).toString('hex')}`)
|
||||
const tempChartPath = join(tempPath, `chart_TODO_MAKE_UNIQUE`)
|
||||
|
||||
mkdir(tempChartPath, this.cancelable(err => {
|
||||
if (err) {
|
||||
@@ -114,7 +114,7 @@ export class FilesystemChecker {
|
||||
* Wraps a function that is able to be prevented if `this.cancelCheck()` was called.
|
||||
*/
|
||||
private cancelable<F extends AnyFunction>(fn: F) {
|
||||
return (...args: Parameters<F>): ReturnType<F> => {
|
||||
return (...args: Parameters<F>): ReturnType<F> | void => {
|
||||
if (this.wasCanceled) { return }
|
||||
return fn(...Array.from(args))
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getSettings } from '../SettingsHandler.ipc'
|
||||
import { settings } from '../SettingsHandler.ipc'
|
||||
|
||||
interface EventCallback {
|
||||
'waitProgress': (remainingSeconds: number, totalSeconds: number) => void
|
||||
@@ -33,10 +33,10 @@ class GoogleTimer {
|
||||
* Check the state of the callbacks and call them if necessary.
|
||||
*/
|
||||
private updateCallbacks() {
|
||||
if (this.hasTimerEnded() && this.callbacks.complete != undefined) {
|
||||
if (this.hasTimerEnded() && this.callbacks.complete !== undefined) {
|
||||
this.endTimer()
|
||||
} else if (this.callbacks.waitProgress != undefined) {
|
||||
const delay = getSettings().rateLimitDelay
|
||||
} else if (this.callbacks.waitProgress !== undefined) {
|
||||
const delay = settings.rateLimitDelay
|
||||
this.callbacks.waitProgress(delay - this.rateLimitCounter, delay)
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ class GoogleTimer {
|
||||
* Checks if enough time has elapsed since the last timer activation.
|
||||
*/
|
||||
private hasTimerEnded() {
|
||||
return this.rateLimitCounter > getSettings().rateLimitDelay
|
||||
return this.rateLimitCounter > settings.rateLimitDelay
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ class GoogleTimer {
|
||||
this.rateLimitCounter = 0
|
||||
const completeCallback = this.callbacks.complete
|
||||
this.callbacks = {}
|
||||
completeCallback()
|
||||
completeCallback?.()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user