Skip to content

Commit

Permalink
优化任务下载状态显示
Browse files Browse the repository at this point in the history
  • Loading branch information
lyswhut committed Dec 30, 2023
1 parent 2337a3e commit 1de087e
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 8 deletions.
1 change: 1 addition & 0 deletions publish/changeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- 优化搜索框交互逻辑,防止鼠标操作时意外搜索候选列表的内容
- 添加对wy源某些歌曲有问题的歌词进行修复
- 改进本地音乐在线信息的匹配机制
- 优化任务下载状态显示,现在下载时若数据传输完成但数据写入未完成时会显示相应的状态

### 修复

Expand Down
2 changes: 2 additions & 0 deletions src/common/types/download_list.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ declare global {
speed: string
downloaded: number
total: number
writeQueue: number
}

interface DownloadTaskActionBase <A> {
Expand Down Expand Up @@ -50,6 +51,7 @@ declare global {
total: number
progress: number
speed: string
writeQueue: number
metadata: {
musicInfo: LX.Music.MusicInfoOnline
url: string | null
Expand Down
38 changes: 32 additions & 6 deletions src/common/utils/download/Downloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { request, type Options as RequestOptions } from './request'

export interface Options {
forceResume: boolean
timeout: number
requestOptions: RequestOptions
}

Expand All @@ -23,6 +24,7 @@ const defaultRequestOptions: Options['requestOptions'] = {
}
const defaultOptions: Options = {
forceResume: true,
timeout: 20_000,
requestOptions: { ...defaultRequestOptions },
}

Expand All @@ -41,6 +43,7 @@ class Task extends EventEmitter {
private redirectNum = 0
private dataWriteQueueLength = 0
private closeWaiting = false
private timeout: null | NodeJS.Timeout = null


constructor(url: string, savePath: string, filename: string, options: Partial<Options> = {}) {
Expand Down Expand Up @@ -69,6 +72,8 @@ class Task extends EventEmitter {
this.progress.speed = 0
this.dataWriteQueueLength = 0
this.closeWaiting = false
this.__clearTimeout()
this.__startTimeout()
if (startByte) this.requestOptions.headers!.range = `bytes=${startByte}-${endByte}`

if (!path) return
Expand Down Expand Up @@ -144,6 +149,7 @@ class Task extends EventEmitter {
}
this.status = STATUS.failed
this.emit('fail', response)
this.__clearTimeout()
this.__closeRequest()
void this.__closeWriteStream()
return
Expand All @@ -156,6 +162,7 @@ class Task extends EventEmitter {
return
}
this.status = STATUS.running
this.__startTimeout()
response
.on('data', this.__handleWriteData.bind(this))
.on('error', err => { this.__handleError(err) })
Expand Down Expand Up @@ -222,6 +229,7 @@ class Task extends EventEmitter {

__handleComplete() {
if (this.status == STATUS.error) return
this.__clearTimeout()
void this.__closeWriteStream().then(() => {
if (this.progress.downloaded == this.progress.total) {
this.status = STATUS.completed
Expand All @@ -237,6 +245,7 @@ class Task extends EventEmitter {
__handleError(error: Error) {
if (this.status == STATUS.error) return
this.status = STATUS.error
this.__clearTimeout()
this.__closeRequest()
void this.__closeWriteStream()
if (error.message == 'aborted') return
Expand Down Expand Up @@ -304,9 +313,11 @@ class Task extends EventEmitter {
return
}
this.dataWriteQueueLength++
this.__startTimeout()
this.__calculateProgress(chunk.length)
this.ws.write(chunk, err => {
this.dataWriteQueueLength--
if (this.status == STATUS.running) this.__calculateProgress(0)
if (err) {
console.log(err)
this.__handleError(err)
Expand All @@ -322,24 +333,38 @@ class Task extends EventEmitter {
let chunkLen = chunk.length
let isOk
if (chunkLen >= resumeLastChunkLen) {
isOk = chunk.slice(0, resumeLastChunkLen).toString('hex') === this.resumeLastChunk!.toString('hex')
isOk = chunk.subarray(0, resumeLastChunkLen).toString('hex') === this.resumeLastChunk!.toString('hex')
if (!isOk) return null

this.resumeLastChunk = null
return chunk.slice(resumeLastChunkLen)
return chunk.subarray(resumeLastChunkLen)
} else {
isOk = chunk.slice(0, chunkLen).toString('hex') === this.resumeLastChunk!.slice(0, chunkLen).toString('hex')
isOk = chunk.subarray(0, chunkLen).toString('hex') === this.resumeLastChunk!.subarray(0, chunkLen).toString('hex')
if (!isOk) return null
this.resumeLastChunk = this.resumeLastChunk!.slice(chunkLen)
return chunk.slice(chunkLen)
this.resumeLastChunk = this.resumeLastChunk!.subarray(chunkLen)
return chunk.subarray(chunkLen)
}
}

async __handleStop() {
this.__clearTimeout()
this.__closeRequest()
return this.__closeWriteStream()
}

private __clearTimeout() {
if (!this.timeout) return
clearTimeout(this.timeout)
this.timeout = null
}

private __startTimeout() {
this.__clearTimeout()
this.timeout = setTimeout(() => {
this.__handleError(new Error('download timeout'))
}, this.options.timeout)
}

__calculateProgress(receivedBytes: number) {
const currentTime = performance.now()
const elaspsedTime = currentTime - this.statsEstimate.time
Expand All @@ -350,7 +375,7 @@ class Task extends EventEmitter {


// emit the progress every second or if finished
if (progress.downloaded === progress.total || elaspsedTime > 1000) {
if ((progress.downloaded === progress.total && this.dataWriteQueueLength == 0) || elaspsedTime > 1000) {
this.statsEstimate.time = currentTime
this.statsEstimate.bytes = progress.downloaded - this.statsEstimate.prevBytes
this.statsEstimate.prevBytes = progress.downloaded
Expand All @@ -359,6 +384,7 @@ class Task extends EventEmitter {
downloaded: progress.downloaded,
progress: progress.progress,
speed: this.statsEstimate.bytes,
writeQueue: this.dataWriteQueueLength,
})
}
}
Expand Down
1 change: 1 addition & 0 deletions src/common/utils/download/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const createDownload = ({
speed,
downloaded: stats.downloaded,
total: stats.total,
writeQueue: stats.writeQueue,
})
// if (debugDownload) {
// const downloaded = sizeFormate(stats.downloaded)
Expand Down
1 change: 1 addition & 0 deletions src/lang/en-us.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"download_status_error_write": "The song save location is occupied or does not have write permission, please try to change the song save directory or restart the software or restart the computer, the error details:",
"download_status_start": "start download",
"download_status_url_geting": "Getting music link...",
"download_status_write_queue": "Data is being written ({num})",
"duplicate_list_tip": "You have favorited this list [{name}] before, do you need to update the songs in it?",
"export": "Export",
"fullscreen_exit": "Exit Full Screen",
Expand Down
1 change: 1 addition & 0 deletions src/lang/zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"download_status_error_write": "歌曲保存位置被占用或没有写入权限,请尝试更改歌曲保存目录或重启软件或重启电脑,错误详情:",
"download_status_start": "开始下载",
"download_status_url_geting": "音乐链接获取中...",
"download_status_write_queue": "数据写入中({num})",
"duplicate_list_tip": "你之前已收藏过该列表 [{name}],是否需要更新里面的歌曲?",
"export": "导出",
"fullscreen_exit": "退出全屏",
Expand Down
1 change: 1 addition & 0 deletions src/lang/zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"download_status_error_write": "歌曲儲存位置被佔用或沒有寫入權限,請嘗試變更歌曲儲存目錄或重新啟動軟體或重新啟動電腦,錯誤詳情:",
"download_status_start": "開始下載",
"download_status_url_geting": "音樂連結獲取中...",
"download_status_write_queue": "資料寫入中({num})",
"duplicate_list_tip": "你之前已收藏過該清單 [{name}],是否需要更新裡面的歌曲?",
"export": "匯出",
"fullscreen_exit": "退出全螢幕",
Expand Down
1 change: 1 addition & 0 deletions src/main/worker/dbService/modules/download/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const initDownloadList = () => {
total: item.progress_total,
progress: item.progress_total ? parseInt((item.progress_downloaded / item.progress_total).toFixed(2)) * 100 : 0,
speed: '',
writeQueue: 0,
metadata: {
musicInfo,
url: item.url,
Expand Down
12 changes: 10 additions & 2 deletions src/renderer/store/download/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,17 @@ const updateFilePath = (downloadInfo: LX.Download.ListItem, filePath: string) =>
}

const setProgress = (downloadInfo: LX.Download.ListItem, progress: LX.Download.ProgressInfo) => {
downloadInfo.progress = progress.progress
downloadInfo.total = progress.total
downloadInfo.downloaded = progress.downloaded
downloadInfo.speed = progress.speed
downloadInfo.writeQueue = progress.writeQueue
if (progress.progress == 100) {
downloadInfo.speed = ''
downloadInfo.progress = 99.99
setStatusText(downloadInfo, window.i18n.t('download_status_write_queue', { num: progress.writeQueue }))
} else {
downloadInfo.speed = progress.speed
downloadInfo.progress = progress.progress
}
throttleUpdateTask([downloadInfo])
}

Expand Down Expand Up @@ -248,6 +255,7 @@ const handleStartTask = async(downloadInfo: LX.Download.ListItem) => {
setStatus(downloadInfo, DOWNLOAD_STATUS.RUN)
break
case 'complete':
downloadInfo.progress = 100
saveMeta(downloadInfo)
downloadLyric(downloadInfo)
void window.lx.worker.download.removeTask(downloadInfo.id)
Expand Down
1 change: 1 addition & 0 deletions src/renderer/worker/download/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ const createTask = async(downloadInfo: LX.Download.ListItem, savePath: string, s
downloadInfo.downloaded = status.downloaded
downloadInfo.progress = status.progress
downloadInfo.speed = status.speed
downloadInfo.writeQueue = status.writeQueue
sendAction(downloadInfo.id, { action: 'progress', data: status })
// console.log(status)
},
Expand Down
1 change: 1 addition & 0 deletions src/renderer/worker/download/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const createDownloadInfo = (musicInfo: LX.Music.MusicInfoOnline, type: LX
total: 0,
progress: 0,
speed: '',
writeQueue: 0,
metadata: {
musicInfo,
url: null,
Expand Down

0 comments on commit 1de087e

Please sign in to comment.