@samitouri / QOSami-HFS / commits / 7e2af854

fix: upload: faulty rename of nested entries (pick-folder)

Massimo Melina committed May 25, 2025 at 15:22 UTC 7e2af8541d02055c060a4bf405eeffa93d67e33b
2 files changed +18 -11
frontend/src/upload.ts
+14 -5
@@ -104,13 +104,17 @@ export function showUpload() {
104 rec.comment = s || undefined
105 },
106 async edit(rec) {
107 - const value = rec.file.name
107 + const value = rec.path || getFilePath(rec.file)
108 const s = await promptDialog(t('upload_name', "Upload with new name"), {
109 value,
110 - onField: el => el.setSelectionRange(0, value.lastIndexOf('.')),
110 + onField: el => {
111 + const ofs = value.lastIndexOf('/') + 1 // browsers picking a folder use / as separator even on Windows
112 + const end = value.slice(ofs).lastIndexOf('.')
113 + el.setSelectionRange(ofs, end < 0 ? value.length : ofs + end)
114 + },
115 })
116 if (!s) return
113 - rec.name = s
117 + rec.path = s
118 },
119 },
120 }),
@@ -177,7 +181,7 @@ function FileList({ entries, actions }: { entries: ToUpload[], actions: { [icon:
181 cb && iconBtn(icon, () => cb(entries[i]), { className: `action-${icon}` })) ),
182 h('td', {}, formatBytes(e.file.size)),
183 h('td', {},
180 - h('span', {}, e.name || getFilePath(entries[i].file)),
184 + h('span', {}, e.path || getFilePath(entries[i].file)),
185 working && h('span', { className: 'upload-progress', title }, formatBytes(partial)),
186 working && hashing && h('span', { className: 'upload-hashing' }, t`Considering resume`, ' (', formatPerc(hashing), ')'),
187 working && h('progress', { className: 'upload-progress-bar', title, max: 1, value: _.round(progress, 3) }), // round for fewer dom updates
@@ -235,7 +239,12 @@ export function UploadStatus({ snapshot, ...props }: { snapshot?: INTERNAL_Snaps
239 [msgErrors, errors]
240 ] as const).map(([msg, list], i) =>
241 msg && h('div', { key: i }, msg, h('ul', {},
238 - list.map((x, i) => h('li', { key: i }, x.name || x.file.name, prefix(' (', x.error, ')'))) )))
242 + list.map((x, i) => h('li', { key: i },
243 + x.path || getFilePath(x.file),
244 + prefix(' (', x.error, ')')
245 + ))
246 + ))
247 + )
248 ))
249 }
250 }
frontend/src/uploadQueue.ts
+4 -6
@@ -1,7 +1,7 @@
1 import {
2 HTTP_CONFLICT, HTTP_MESSAGES, HTTP_PAYLOAD_TOO_LARGE, HTTP_RANGE_NOT_SATISFIABLE, HTTP_NOT_MODIFIED,
3 UPLOAD_RESUMABLE, UPLOAD_REQUEST_STATUS, UPLOAD_RESUMABLE_HASH,
4 - buildUrlQueryString, dirname, getHFS, pathEncode, pendingPromise, prefix, randomId, tryJson, with_, wait, waitFor,
4 + buildUrlQueryString, getHFS, pathEncode, pendingPromise, prefix, randomId, tryJson, with_, wait, waitFor,
5 } from '@hfs/shared'
6 import { state } from './state'
7 import { getNotifications } from '@hfs/shared/api'
@@ -15,7 +15,7 @@ import { hfsEvent, onHfsEvent } from './misc'
15 import i18n from './i18n'
16 const { t } = i18n
17
18 -export interface ToUpload { file: File, comment?: string, name?: string, to?: string, error?: string }
18 +export interface ToUpload { file: File, comment?: string, path?: string, to?: string, error?: string }
19 export const uploadState = proxy<{
20 done: (ToUpload & { response?: any })[] // res will contain the response from the server,
21 doneByte: number
@@ -156,9 +156,7 @@ export async function startUpload(toUpload: ToUpload, to: string, startingResume
156 stuckSince = Date.now()
157 lastProgress = e.loaded
158 }
159 - let uploadPath = getFilePath(toUpload.file)
160 - if (toUpload.name)
161 - uploadPath = prefix('', dirname(uploadPath), '/') + toUpload.name
159 + const uploadPath = toUpload.path || getFilePath(toUpload.file)
160 const partial = splitSize && offset + splitSize < fullSize
161 req.open('PUT', to + pathEncode(uploadPath) + buildUrlQueryString({
162 notifications: notificationChannel,
@@ -192,7 +190,7 @@ export async function startUpload(toUpload: ToUpload, to: string, startingResume
190 return hfsEvent(PREFIX + data.path, data.hash)
191 if (name === UPLOAD_RESUMABLE) {
192 waitSecondChunk.resolve()
195 - if (uploading.name !== data.path) return // is it about current file?
193 + if (uploading.path !== data.path) return // is it about current file?
194 if (data.written)
195 return lastWrittenReceived = data.written
196 const {size} = data //TODO use toUpload?