fix: improve file upload performance with batch processing and progress feedback

- Add batch processing (5 files concurrently) to uploadNotes function
- Use Promise.allSettled for parallel file processing
- Add setTimeout(0) between batches to yield to event loop
- Show loading toast when uploading more than 5 files
- Add translation keys for uploading progress (en, zh-cn, zh-tw)

Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-11-20 06:25:11 +00:00
parent be99f4df71
commit a95e776699
5 changed files with 46 additions and 13 deletions

View File

@ -2175,7 +2175,8 @@
"untitled_folder": "New Folder",
"untitled_note": "Untitled Note",
"upload_failed": "Note upload failed",
"upload_success": "Note uploaded success"
"upload_success": "Note uploaded success",
"uploading_files": "Uploading {{count}} files..."
},
"notification": {
"assistant": "Assistant Response",

View File

@ -2175,7 +2175,8 @@
"untitled_folder": "新文件夹",
"untitled_note": "无标题笔记",
"upload_failed": "笔记上传失败",
"upload_success": "笔记上传成功"
"upload_success": "笔记上传成功",
"uploading_files": "正在上传 {{count}} 个文件..."
},
"notification": {
"assistant": "助手响应",

View File

@ -2175,7 +2175,8 @@
"untitled_folder": "新資料夾",
"untitled_note": "無標題筆記",
"upload_failed": "筆記上傳失敗",
"upload_success": "筆記上傳成功"
"upload_success": "筆記上傳成功",
"uploading_files": "正在上傳 {{count}} 個檔案..."
},
"notification": {
"assistant": "助手回應",

View File

@ -621,8 +621,19 @@ const NotesPage: FC = () => {
throw new Error('No folder path selected')
}
// Show loading toast for multiple files to indicate processing
let loadingToast: number | string | undefined
if (files.length > 5) {
loadingToast = window.toast.loading(t('notes.uploading_files', { count: files.length }))
}
const result = await uploadNotes(files, targetFolderPath)
// Dismiss loading toast if shown
if (loadingToast) {
window.toast.dismiss(loadingToast)
}
// 检查上传结果
if (result.fileCount === 0) {
window.toast.warning(t('notes.no_valid_files'))

View File

@ -101,18 +101,37 @@ export async function uploadNotes(files: File[], targetPath: string): Promise<Up
await createFolders(folders)
let fileCount = 0
const BATCH_SIZE = 5 // Process 5 files concurrently to balance performance and responsiveness
for (const file of markdownFiles) {
const { dir, name } = resolveFileTarget(file, basePath)
const { safeName } = await window.api.file.checkFileName(dir, name, true)
const finalPath = `${dir}/${safeName}${MARKDOWN_EXT}`
// Process files in batches to avoid blocking the UI thread
for (let i = 0; i < markdownFiles.length; i += BATCH_SIZE) {
const batch = markdownFiles.slice(i, i + BATCH_SIZE)
// Process current batch in parallel
const results = await Promise.allSettled(
batch.map(async (file) => {
const { dir, name } = resolveFileTarget(file, basePath)
const { safeName } = await window.api.file.checkFileName(dir, name, true)
const finalPath = `${dir}/${safeName}${MARKDOWN_EXT}`
try {
const content = await file.text()
await window.api.file.write(finalPath, content)
fileCount += 1
} catch (error) {
logger.error('Failed to write uploaded file:', error as Error)
const content = await file.text()
await window.api.file.write(finalPath, content)
return true
})
)
// Count successful uploads
results.forEach((result) => {
if (result.status === 'fulfilled') {
fileCount += 1
} else {
logger.error('Failed to write uploaded file:', result.reason)
}
})
// Yield to the event loop between batches to keep UI responsive
if (i + BATCH_SIZE < markdownFiles.length) {
await new Promise((resolve) => setTimeout(resolve, 0))
}
}