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 || '')