refactor: replace fake progress bar with spinner for task creation

移除批量下载时模拟的进度条,改用转圈加载动画。
模拟进度条没有实际意义,单事务创建任务速度已大幅提升。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-09 17:40:16 +08:00
parent c8ee9685b9
commit dcc6b5969e
+15 -39
View File
@@ -49,12 +49,7 @@ export class ParseModalComp implements VanComponent {
formatIndex: State<number> formatIndex: State<number>
}[]> = van.state([]) }[]> = van.state([])
/** 该属性用于在点击”开始下载”按钮后使按钮变为禁用状态,防止多次点击 */ /** 下载状态 */
downloadBtnDisabled = van.state(false)
/** 下载进度 */
downloadProgress = van.state(0)
downloadTotal = van.state(0)
isDownloading = van.state(false) isDownloading = van.state(false)
/** 下载类型:audio 仅音频,video 仅视频,merge 音视频合并 */ /** 下载类型:audio 仅音频,video 仅视频,merge 音视频合并 */
@@ -79,6 +74,16 @@ export class ParseModalComp implements VanComponent {
), ),
// 进度条固定在头部下方 // 进度条固定在头部下方
this.StickyProgress(), this.StickyProgress(),
// 下载时的加载动画
div({
class: 'text-center p-5',
hidden: () => !this.isDownloading.val
},
div({ class: 'spinner-border text-primary', role: 'status' },
span({ class: 'visually-hidden' }, '加载中...')
),
div({ class: 'mt-3' }, '正在创建下载任务...')
),
div({ class: `modal-body vstack gap-3`, tabIndex: -1, style: 'outline: none;' }, div({ class: `modal-body vstack gap-3`, tabIndex: -1, style: 'outline: none;' },
div({ class: 'vstack gap-2', hidden: () => this.errorList.val.length == 0 || !allFinish.val || this.isDownloading.val }, div({ class: 'vstack gap-2', hidden: () => this.errorList.val.length == 0 || !allFinish.val || this.isDownloading.val },
div({ class: 'text-danger' }, () => `以下 ${this.errorList.val.length} 个视频解析失败`), div({ class: 'text-danger' }, () => `以下 ${this.errorList.val.length} 个视频解析失败`),
@@ -138,10 +143,7 @@ export class ParseModalComp implements VanComponent {
download() { download() {
const selectedPlayInfos = this.allPlayInfo.val.filter(info => info.selected.val) const selectedPlayInfos = this.allPlayInfo.val.filter(info => info.selected.val)
const workRoute = this.option.workRoute const workRoute = this.option.workRoute
this.downloadBtnDisabled.val = true
this.isDownloading.val = true this.isDownloading.val = true
this.downloadProgress.val = 0
this.downloadTotal.val = selectedPlayInfos.length
// 需要传递给服务器,需要创建下载任务的数据列表 // 需要传递给服务器,需要创建下载任务的数据列表
createTask(selectedPlayInfos.map((info, index) => { createTask(selectedPlayInfos.map((info, index) => {
@@ -185,27 +187,12 @@ export class ParseModalComp implements VanComponent {
...activeVideoInfo ...activeVideoInfo
}) })
})).then(() => { })).then(() => {
this.downloadProgress.val = this.downloadTotal.val
setTimeout(() => {
workRoute.parseModal.hide() workRoute.parseModal.hide()
}, 500)
}).catch(error => { }).catch(error => {
alert(error.message) alert(error.message)
}).finally(() => { }).finally(() => {
this.downloadBtnDisabled.val = false
this.isDownloading.val = false this.isDownloading.val = false
}) })
// 更新进度
const updateProgress = () => {
if (this.downloadProgress.val < this.downloadTotal.val) {
this.downloadProgress.val++
if (this.isDownloading.val) {
setTimeout(updateProgress, 50)
}
}
}
setTimeout(updateProgress, 100)
} }
ParseProgress() { ParseProgress() {
@@ -218,30 +205,19 @@ export class ParseModalComp implements VanComponent {
) )
} }
/** 固定在顶部的进度条 */ /** 固定在顶部的进度条(解析进度) */
StickyProgress() { StickyProgress() {
return div({ return div({
class: 'sticky-top bg-body p-3 border-bottom', class: 'sticky-top bg-body p-3 border-bottom',
hidden: () => this.totalCount.val == this.finishCount.val && !this.isDownloading.val, hidden: () => this.totalCount.val == this.finishCount.val,
style: 'z-index: 10;' style: 'z-index: 10;'
}, },
this.ParseProgress(), this.ParseProgress(),
this.DownloadProgress(),
)
}
DownloadProgress() {
return div({ class: 'vstack gap-3', hidden: () => !this.isDownloading.val },
div({ class: 'text-center fs-5' }, () => `正在创建下载任务 (${this.downloadProgress.val}/${this.downloadTotal.val})`),
div({ class: 'progress' }, div({
class: 'progress-bar progress-bar-striped progress-bar-animated',
style: () => `width: ${this.downloadProgress.val / this.downloadTotal.val * 100}%`
},)),
) )
} }
ListGroup() { ListGroup() {
return () => div({ class: 'list-group', hidden: () => this.totalCount.val != this.finishCount.val }, return () => div({ class: 'list-group', hidden: () => this.totalCount.val != this.finishCount.val || this.isDownloading.val },
this.allPlayInfo.val.filter(info => info.info) this.allPlayInfo.val.filter(info => info.info)
.sort((a, b) => a.page.page - b.page.page) .sort((a, b) => a.page.page - b.page.page)
.map(info => { .map(info => {
@@ -355,7 +331,7 @@ export class ParseModalComp implements VanComponent {
_that.download() _that.download()
}, },
hidden: () => !allFinish.val, hidden: () => !allFinish.val,
disabled: () => selectedCount.val <= 0 || _that.downloadBtnDisabled.val disabled: () => selectedCount.val <= 0 || _that.isDownloading.val
}, '开始下载'), }, '开始下载'),
) )
} }