feat: image upload on articles
This commit is contained in:
1 parent
d4fcfb2bba
commit
938263cd6a
12 files changed
+1436
-65
No files matched your search
@@ -0,0 +1,59 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
export interface UploadProgress {
|
||||
loaded: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export type UploadOutcome =
|
||||
| { kind: 'success'; location: string }
|
||||
| { kind: 'rejected'; body: string }
|
||||
| { kind: 'failed' }
|
||||
|
||||
export function useImageUpload() {
|
||||
const progress = ref<UploadProgress>({ loaded: 0, total: 0 })
|
||||
let activeRequest: XMLHttpRequest | null = null
|
||||
|
||||
function abort() {
|
||||
activeRequest?.abort()
|
||||
activeRequest = null
|
||||
}
|
||||
|
||||
function start(articleId: number, file: File): Promise<UploadOutcome> {
|
||||
progress.value = { loaded: 0, total: file.size }
|
||||
return new Promise((resolve) => {
|
||||
const request = new XMLHttpRequest()
|
||||
activeRequest = request
|
||||
request.open('POST', `/v1/article/${articleId}/image`)
|
||||
request.withCredentials = true
|
||||
request.upload.addEventListener('progress', (event) => {
|
||||
progress.value = { loaded: event.loaded, total: event.total }
|
||||
})
|
||||
request.addEventListener('load', () => {
|
||||
activeRequest = null
|
||||
if (request.status === 201) {
|
||||
const body = JSON.parse(request.responseText) as { location: string }
|
||||
resolve({ kind: 'success', location: body.location })
|
||||
return
|
||||
}
|
||||
if (request.status === 400) {
|
||||
resolve({ kind: 'rejected', body: request.responseText })
|
||||
return
|
||||
}
|
||||
resolve({ kind: 'failed' })
|
||||
})
|
||||
request.addEventListener('error', () => {
|
||||
activeRequest = null
|
||||
resolve({ kind: 'failed' })
|
||||
})
|
||||
request.addEventListener('abort', () => {
|
||||
activeRequest = null
|
||||
})
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
request.send(formData)
|
||||
})
|
||||
}
|
||||
|
||||
return { progress, start, abort }
|
||||
}
|
||||
Reference in new issue
Block a user