@samitouri / QOSami-HFS / commits / 5d1ee92a

better code

Massimo Melina committed May 23, 2025 at 13:31 UTC 5d1ee92a4f37fce52735b116049c043f36bc9101
3 files changed +14 -15
frontend/src/upload.ts
+1 -1
@@ -219,7 +219,7 @@ export function UploadStatus({ snapshot, ...props }: { snapshot?: INTERNAL_Snaps
219 asText: true,
220 successFeedback: true,
221 onClick() {
222 - copyTextToClipboard(done.map(x => location.origin + x.res.uri).join('\n'))
222 + copyTextToClipboard(done.map(x => location.origin + x.response.uri).join('\n'))
223 operationSuccessful()
224 }
225 }),
frontend/src/uploadQueue.ts
+10 -11
@@ -16,7 +16,7 @@ const { t } = i18n
16
17 export interface ToUpload { file: File, comment?: string, name?: string, to?: string, error?: string }
18 export const uploadState = proxy<{
19 - done: (ToUpload & { res?: any })[]
19 + done: (ToUpload & { response?: any })[] // res will contain the response from the server,
20 doneByte: number
21 errors: ToUpload[]
22 skipped: ToUpload[]
@@ -105,14 +105,13 @@ export async function startUpload(toUpload: ToUpload, to: string, startingResume
105 do { // at least one iteration, even for empty files
106 offset = Math.max(splitResume, lastWrittenReceived)
107 const req = currentReq = new XMLHttpRequest()
108 - const finished = pendingPromise()
108 + const requestIsOver = pendingPromise()
109 stuckSince = Date.now()
110 req.onloadend = async () => {
111 try {
112 currentReq = undefined
113 const status = overrideStatus || req.status
114 if (resuming) { // resuming requested
115 - finished.resolve()
115 resuming = false // this behavior is only for once, for cancellation of the upload that is in the background while resume is confirmed
116 stopLooping = true
117 return
@@ -121,8 +120,8 @@ export async function startUpload(toUpload: ToUpload, to: string, startingResume
120 uploadState.skipped.push(toUpload)
121 else if (status >= 400)
122 error(status)
124 - else if (!status) // request failed at a network level, so try again, but not too often
125 - return await wait(2000)
123 + else if (!status) // request failed at a network level, so try again same file (return), but not too often (wait)
124 + return await wait(2000) // wait before resolving `finished`
125 else {
126 if (splitSize) {
127 splitResume += splitSize
@@ -130,14 +129,14 @@ export async function startUpload(toUpload: ToUpload, to: string, startingResume
129 }
130 stopLooping = true
131 waitSecondChunk.resolve() // we finished, no need to wait
133 - uploadState.done.push({ ...toUpload, res: tryJson(req.responseText) })
132 + uploadState.done.push({ ...toUpload, response: tryJson(req.responseText) })
133 uploadState.doneByte += toUpload!.file.size
134 reloadOnClose = true
135 }
137 - finished.then(next)
136 + requestIsOver.then(workNextFile)
137 }
138 finally {
140 - finished.resolve()
139 + requestIsOver.resolve()
140 }
141 }
142 let lastProgress = 0
@@ -162,7 +161,7 @@ export async function startUpload(toUpload: ToUpload, to: string, startingResume
161 ...with_(state.uploadOnExisting, x => x !== 'rename' && { existing: x }), // rename is the default
162 }), true)
163 req.send(toUpload.file.slice(offset, splitSize ? offset + splitSize : undefined))
165 - await finished
164 + await requestIsOver
165 if (!startingResume && notificationSource?.readyState === OPEN) // wait only if notifications are currently available
166 await waitSecondChunk
167 } while (!stopLooping && offset < fullSize)
@@ -210,7 +209,7 @@ export async function startUpload(toUpload: ToUpload, to: string, startingResume
209 resuming = true
210 console.debug('resuming upload', size.toLocaleString())
211 preserveTempFile = undefined
213 - abortCurrentUpload()
212 + abortCurrentUpload() // `resuming` will avoid this to be considered skipped
213 await wait(500) // be sure the server had the time to react to the abort() and unlocked the file, or our next request will fail
214 return startUpload(toUpload, to, size)
215 }
@@ -235,7 +234,7 @@ export async function startUpload(toUpload: ToUpload, to: string, startingResume
234 closeLastDialog = alertDialog(msg, 'error')?.close
235 }
236
238 - function next() {
237 + function workNextFile() {
238 stopLooping = true
239 uploadState.uploading = undefined
240 uploadState.partial = 0
src/connections.ts
+3 -3
@@ -12,12 +12,12 @@ export class Connection {
12 got = 0
13 outSpeed?: number
14 inSpeed?: number
15 - ctx?: Context
15 + ctx?: Context // this is set externally, during koa middleware, using updateConnectionForCtx, but only for regular requests; some connections may never have a ctx
16 country?: string
17 private _cachedIp?: string
18 [rest:symbol]: any // let other modules add extra data, but using symbols to avoid name collision
19
20 - constructor(readonly socket: Socket) {
20 + constructor(public readonly socket: Socket) {
21 all.push(this)
22 socket.on('close', () => {
23 all.splice(all.indexOf(this), 1)
@@ -83,7 +83,7 @@ export function updateConnection(conn: Connection, change: Partial<Connection>,
83
84 export const disconnectionsLog: { ts: Date, ip: string, country?: string, msg?: string }[] = []
85
86 -export function disconnect(what: Context | Socket, debugLog='') {
86 +export function disconnect(what: Context | Socket | Connection, debugLog='') {
87 if ('socket' in what)
88 what = what.socket
89 const ip = normalizeIp(what.remoteAddress || '')