mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-02-17 13:20:52 +08:00
feat(upload): almost done
This commit is contained in:
parent
54b0adf576
commit
644686f1fd
@ -24,6 +24,8 @@ app.post(
|
||||
upload.any(),
|
||||
function (req, res, next) {
|
||||
if (!fs.existsSync(dest)) fs.mkdirSync(dest)
|
||||
console.log(req.headers)
|
||||
console.log(req.body)
|
||||
res.send('very good')
|
||||
}
|
||||
)
|
||||
|
@ -49,19 +49,20 @@ function createId () {
|
||||
}
|
||||
|
||||
/**
|
||||
* fils status ['pending', 'uploading', 'done', 'removed', 'error']
|
||||
* fils status ['pending', 'uploading', 'finished', 'removed', 'error']
|
||||
*/
|
||||
function XHRHandlers (componentInstance, file) {
|
||||
function XHRHandlers (componentInstance, file, XHR) {
|
||||
const change = componentInstance.change
|
||||
const XHRMap = componentInstance.XHRMap
|
||||
return {
|
||||
handleXHRLoad (e) {
|
||||
const fileAfterChange = Object.assign({}, file, {
|
||||
status: 'done',
|
||||
let fileAfterChange = Object.assign({}, file, {
|
||||
status: 'finished',
|
||||
percentage: 100,
|
||||
file: null
|
||||
})
|
||||
XHRMap.delete(file.id)
|
||||
fileAfterChange = componentInstance.onFinish(fileAfterChange, XHR.response) || fileAfterChange
|
||||
change(fileAfterChange, e)
|
||||
},
|
||||
handleXHRAbort (e) {
|
||||
@ -92,7 +93,7 @@ function XHRHandlers (componentInstance, file) {
|
||||
}
|
||||
|
||||
function registerHandler (componentInstance, file, request) {
|
||||
const handlers = XHRHandlers(componentInstance, file)
|
||||
const handlers = XHRHandlers(componentInstance, file, request)
|
||||
request.onabort = handlers.handleXHRAbort
|
||||
request.onerror = handlers.handleXHRError
|
||||
request.onload = handlers.handleXHRLoad
|
||||
@ -104,7 +105,7 @@ function registerHandler (componentInstance, file, request) {
|
||||
function setHeaders (request, headers) {
|
||||
if (!headers) return
|
||||
Object.keys(headers).forEach(key => {
|
||||
request.setRequestHeader(request, headers[key])
|
||||
request.setRequestHeader(key, headers[key])
|
||||
})
|
||||
}
|
||||
|
||||
@ -138,10 +139,10 @@ function submit (
|
||||
const request = new XMLHttpRequest()
|
||||
componentInstance.XHRMap.set(file.id, request)
|
||||
request.withCredentials = withCredentials
|
||||
setHeaders(request, headers, file)
|
||||
appendData(formData, data, file)
|
||||
registerHandler(componentInstance, file, request)
|
||||
request.open(method, action)
|
||||
request.open(method.toUpperCase(), action)
|
||||
setHeaders(request, headers, file)
|
||||
request.send(formData)
|
||||
const fileAfterChange = Object.assign({}, file, {
|
||||
status: 'uploading'
|
||||
@ -186,11 +187,11 @@ export default {
|
||||
default: false
|
||||
},
|
||||
data: {
|
||||
type: [Boolean, Function],
|
||||
type: [Object, Function],
|
||||
default: null
|
||||
},
|
||||
headers: {
|
||||
type: Object,
|
||||
type: [Object, Function],
|
||||
default: null
|
||||
},
|
||||
withCredentials: {
|
||||
@ -209,7 +210,12 @@ export default {
|
||||
type: Function,
|
||||
default: () => true
|
||||
},
|
||||
onFinish: {
|
||||
type: Function,
|
||||
default: file => file
|
||||
},
|
||||
onDownload: {
|
||||
/** currently of no usage */
|
||||
type: Function,
|
||||
default: () => true
|
||||
},
|
||||
@ -231,7 +237,7 @@ export default {
|
||||
},
|
||||
showCancelButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: true
|
||||
},
|
||||
showRemoveButton: {
|
||||
type: Boolean,
|
||||
@ -289,6 +295,7 @@ export default {
|
||||
this.dragOver = false
|
||||
},
|
||||
handleActivatorDrop (e) {
|
||||
if (!this.draggerInside) return
|
||||
e.preventDefault()
|
||||
const dataTransfer = e.dataTransfer
|
||||
const files = dataTransfer.files || []
|
||||
@ -317,14 +324,17 @@ export default {
|
||||
this.submit()
|
||||
}
|
||||
},
|
||||
submit () {
|
||||
submit (fileId) {
|
||||
const method = this.method
|
||||
const action = this.action
|
||||
const withCredentials = this.withCredentials
|
||||
const headers = this.headers
|
||||
const data = this.data
|
||||
const fieldName = this.name
|
||||
this.syntheticFileList.forEach(file => {
|
||||
const filesToUpload = fileId ? this.syntheticFileList.filter(
|
||||
file => file.id === fileId
|
||||
) : this.syntheticFileList
|
||||
filesToUpload.forEach(file => {
|
||||
if (file.status === 'pending') {
|
||||
const formData = new FormData()
|
||||
formData.append(fieldName, file)
|
||||
|
@ -22,6 +22,8 @@
|
||||
key="closeOrTrash"
|
||||
circle
|
||||
size="tiny"
|
||||
ghost
|
||||
:type="buttonType"
|
||||
@click="handleRemoveOrCancelClick"
|
||||
>
|
||||
<template v-slot:icon>
|
||||
@ -36,6 +38,8 @@
|
||||
key="download"
|
||||
circle
|
||||
size="tiny"
|
||||
ghost
|
||||
:type="buttonType"
|
||||
@click="handleDownloadClick"
|
||||
>
|
||||
<template v-slot:icon>
|
||||
@ -46,7 +50,7 @@
|
||||
</div>
|
||||
<n-upload-progress
|
||||
:show="showProgress"
|
||||
:percentage="file.percentage"
|
||||
:percentage="file.percentage || 0"
|
||||
:status="progressStatus"
|
||||
/>
|
||||
</a>
|
||||
@ -94,10 +98,14 @@ export default {
|
||||
},
|
||||
progressStatus () {
|
||||
const file = this.file
|
||||
if (file.status === 'done') return 'success'
|
||||
if (file.status === 'finished') return 'success'
|
||||
if (file.status === 'error') return 'error'
|
||||
return 'info'
|
||||
},
|
||||
buttonType () {
|
||||
if (this.file.status === 'error') return 'error'
|
||||
return undefined
|
||||
},
|
||||
showProgress () {
|
||||
const file = this.file
|
||||
return file.status === 'uploading'
|
||||
@ -110,18 +118,19 @@ export default {
|
||||
showRemoveButton () {
|
||||
if (!this.NUpload.showRemoveButton) return false
|
||||
const file = this.file
|
||||
return ['done'].includes(file.status)
|
||||
return ['finished'].includes(file.status)
|
||||
},
|
||||
showDownloadButton () {
|
||||
if (!this.NUpload.showDownloadButton) return false
|
||||
const file = this.file
|
||||
return ['done'].includes(file.status)
|
||||
return ['finished'].includes(file.status)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleRemoveOrCancelClick () {
|
||||
handleRemoveOrCancelClick (e) {
|
||||
e.preventDefault()
|
||||
const file = this.file
|
||||
if (['done', 'pending', 'error'].includes(file.status)) {
|
||||
if (['finished', 'pending', 'error'].includes(file.status)) {
|
||||
this.handleRemove(file)
|
||||
} else if (['uploading'].includes(file.status)) {
|
||||
this.handleAbort(file)
|
||||
@ -129,7 +138,8 @@ export default {
|
||||
console.error('[naive-ui/upload]: the button clicked type is unknown.')
|
||||
}
|
||||
},
|
||||
handleDownloadClick () {
|
||||
handleDownloadClick (e) {
|
||||
e.preventDefault()
|
||||
this.onDownload(this.file)
|
||||
},
|
||||
handleRemove (file) {
|
||||
@ -137,28 +147,27 @@ export default {
|
||||
const XHRMap = NUpload.XHRMap
|
||||
const change = NUpload.change
|
||||
Promise.resolve(
|
||||
NUpload.onRemove(file)
|
||||
NUpload.onRemove(Object.assign({}, file))
|
||||
).then(
|
||||
res => {
|
||||
if (res === true) {
|
||||
const fileAfterChange = Object.assign({}, file, {
|
||||
status: 'removed'
|
||||
})
|
||||
XHRMap.delete(file.id)
|
||||
change(fileAfterChange, undefined, {
|
||||
remove: true
|
||||
})
|
||||
}
|
||||
if (res === false) return
|
||||
const fileAfterChange = Object.assign({}, file, {
|
||||
status: 'removed'
|
||||
})
|
||||
XHRMap.delete(file.id)
|
||||
change(fileAfterChange, undefined, {
|
||||
remove: true
|
||||
})
|
||||
}
|
||||
)
|
||||
},
|
||||
handleDownload (file) {
|
||||
const NUpload = this.NUpload
|
||||
Promise.resolve(
|
||||
NUpload.onDownload(file)
|
||||
NUpload.onDownload(Object.assign({}, file))
|
||||
).then(
|
||||
res => {
|
||||
if (res === true) {} // do something
|
||||
/** I haven't figure out its usage, so just leave it here */
|
||||
}
|
||||
)
|
||||
},
|
||||
@ -167,7 +176,7 @@ export default {
|
||||
const XHRMap = NUpload.XHRMap
|
||||
const XHR = XHRMap.get(file.id)
|
||||
XHR.abort()
|
||||
this.handleRemove(file)
|
||||
this.handleRemove(Object.assign({}, file))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ export default {
|
||||
},
|
||||
delay: {
|
||||
type: Number,
|
||||
default: 600
|
||||
default: 900
|
||||
}
|
||||
},
|
||||
data () {
|
||||
|
@ -21,7 +21,7 @@
|
||||
border-radius: 6px;
|
||||
border: 1px dashed $--n-alpha-border-color;
|
||||
padding: 24px;
|
||||
transition: border-color .3s $--n-ease-in-out-cubic-bezier, background-color .3s $--n-ease-in-out-cubic-bezier;;
|
||||
transition: border-color .3s $--n-ease-in-out-cubic-bezier, background-color .3s $--n-ease-in-out-cubic-bezier;
|
||||
&:hover {
|
||||
border-color: $--primary-6;
|
||||
}
|
||||
@ -42,7 +42,7 @@
|
||||
@include fade-in-height-expand-transition;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
cursor: default;
|
||||
padding: 0px 12px 0 6px;
|
||||
transition: background-color .3s $--n-ease-in-out-cubic-bezier;
|
||||
border-radius: 6px;
|
||||
@ -55,6 +55,9 @@
|
||||
}
|
||||
}
|
||||
@include m(error-status) {
|
||||
&:hover {
|
||||
background-color: map-get($--upload-file-item-background-color, 'error-hover');
|
||||
}
|
||||
@include b(upload-file-info) {
|
||||
@include e(name) {
|
||||
color: $--error-6;
|
||||
@ -62,14 +65,22 @@
|
||||
}
|
||||
}
|
||||
@include m(success-status) {
|
||||
}
|
||||
@include m(with-url) {
|
||||
@include b(upload-file-info) {
|
||||
@include e(name) {
|
||||
color: $--success-6;
|
||||
}
|
||||
}
|
||||
}
|
||||
@include m(with-url) {
|
||||
cursor: pointer;
|
||||
@include b(upload-file-info) {
|
||||
@include e(name) {
|
||||
color: $--success-6;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: $--success-6;
|
||||
}
|
||||
}
|
||||
}
|
||||
@include b(upload-file-info) {
|
||||
position: relative;
|
||||
padding-top: 6px;
|
||||
@ -77,6 +88,8 @@
|
||||
@include e(name) {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: transparent;
|
||||
@include b(icon) {
|
||||
font-size: 18px;
|
||||
margin-right: 2px;
|
||||
@ -86,7 +99,9 @@
|
||||
}
|
||||
font-size: 14px;
|
||||
color: $--n-secondary-text-color;
|
||||
transition: color .3s $--n-ease-in-out-cubic-bezier;
|
||||
transition:
|
||||
color .3s $--n-ease-in-out-cubic-bezier,
|
||||
text-decoration-color .3s $--n-ease-in-out-cubic-bezier;
|
||||
}
|
||||
@include e(action) {
|
||||
padding-top: inherit;
|
||||
|
@ -1,5 +1,6 @@
|
||||
@mixin setup-dark-upload {
|
||||
$--uploadd-file-item-background-color: (
|
||||
'hover': change-color($--primary-6, $alpha: .15)
|
||||
'hover': change-color($--primary-6, $alpha: .15),
|
||||
'error-hover': change-color($--error-6, $alpha: .15)
|
||||
) !global;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
@mixin setup-light-upload {
|
||||
$--upload-file-item-background-color: (
|
||||
'hover': change-color($--primary-6, $alpha: .1)
|
||||
'hover': change-color($--primary-6, $alpha: .1),
|
||||
'error-hover': change-color($--error-6, $alpha: .1)
|
||||
) !global;
|
||||
}
|
Loading…
Reference in New Issue
Block a user