mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-23 18:29:09 +00:00
Better file type detection
This commit is contained in:
parent
cbda447d5a
commit
024ebfa192
4 changed files with 124 additions and 57 deletions
|
|
@ -95,15 +95,18 @@ export default class Core {
|
|||
addFile (file) {
|
||||
const updatedFiles = Object.assign({}, this.state.files)
|
||||
|
||||
const fileType = file.type.split('/')
|
||||
const fileType = Utils.getFileType(file) ? Utils.getFileType(file).split('/') : ['', '']
|
||||
const fileTypeGeneral = fileType[0]
|
||||
const fileTypeSpecific = fileType[1]
|
||||
const fileExtension = Utils.getFileNameAndExtension(file.name)[1]
|
||||
|
||||
const fileID = Utils.generateFileID(file.name)
|
||||
|
||||
updatedFiles[fileID] = {
|
||||
source: file.source || '',
|
||||
id: fileID,
|
||||
name: file.name,
|
||||
extension: fileExtension,
|
||||
type: {
|
||||
general: fileTypeGeneral,
|
||||
specific: fileTypeSpecific
|
||||
|
|
@ -119,8 +122,10 @@ export default class Core {
|
|||
this.setState({files: updatedFiles})
|
||||
|
||||
if (fileTypeGeneral === 'image') {
|
||||
// this.addImgPreviewToFile(updatedFiles[fileID])
|
||||
Utils.readImage(updatedFiles[fileID].data, (imgEl) => {
|
||||
Utils.readImage(updatedFiles[fileID].data, (err, imgEl) => {
|
||||
if (err) {
|
||||
return this.log(err)
|
||||
}
|
||||
const newImageWidth = 200
|
||||
const newImageHeight = Utils.getProportionalImageHeight(imgEl, newImageWidth)
|
||||
const resizedImgSrc = Utils.resizeImage(imgEl, newImageWidth, newImageHeight)
|
||||
|
|
@ -188,8 +193,6 @@ export default class Core {
|
|||
const updatedFiles = Object.assign({}, this.state.files)
|
||||
updatedFiles[file.id] = file
|
||||
this.setState({files: updatedFiles})
|
||||
// this.log(this.state.uploadedFiles)
|
||||
// this.emitter.emit('file-remove', file.id)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -314,27 +317,6 @@ export default class Core {
|
|||
})
|
||||
|
||||
return
|
||||
|
||||
// Each Plugin can have `run` and/or `install` methods.
|
||||
// `install` adds event listeners and does some non-blocking work, useful for `progressindicator`,
|
||||
// `run` waits for the previous step to finish (user selects files) before proceeding
|
||||
// ['install', 'run'].forEach((method) => {
|
||||
// // First we select only plugins of current type,
|
||||
// // then create an array of runType methods of this plugins
|
||||
// const typeMethods = this.types.filter((type) => this.plugins[type])
|
||||
// .map((type) => this.runType.bind(this, type, method))
|
||||
// // Run waterfall of typeMethods
|
||||
// return Utils.promiseWaterfall(typeMethods)
|
||||
// .then((result) => {
|
||||
// // If results are empty, don't log upload results. Hasn't run yet.
|
||||
// if (result[0] !== undefined) {
|
||||
// this.log(result)
|
||||
// this.log('Upload result -> success!')
|
||||
// return result
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => this.log('Upload result -> failed:', error))
|
||||
// })
|
||||
}
|
||||
|
||||
initSocket (opts) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import mime from 'mime-types'
|
||||
|
||||
/**
|
||||
* A collection of small utility functions that help with dom manipulation, adding listeners,
|
||||
* promises and other good things.
|
||||
|
|
@ -35,10 +37,44 @@ function isTouchDevice () {
|
|||
};
|
||||
|
||||
/**
|
||||
* `querySelectorAll` that returns a normal array instead of fileList
|
||||
* Shorter and fast way to select multiple nodes in the DOM
|
||||
* @param { String|Array } selector - DOM selector or nodes list
|
||||
* @param { Object } ctx - DOM node where the targets of our search will is located
|
||||
* @returns { Object } dom nodes found
|
||||
*/
|
||||
function qsa (selector, context) {
|
||||
return Array.prototype.slice.call((context || document).querySelectorAll(selector) || [])
|
||||
export function $$ (selector, ctx) {
|
||||
var els
|
||||
if (typeof selector === 'string') {
|
||||
els = (ctx || document).querySelectorAll(selector)
|
||||
} else {
|
||||
els = selector
|
||||
return Array.prototype.slice.call(els)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorter and fast way to select a single node in the DOM
|
||||
* @param { String } selector - unique dom selector
|
||||
* @param { Object } ctx - DOM node where the target of our search will is located
|
||||
* @returns { Object } dom node found
|
||||
*/
|
||||
export function $ (selector, ctx) {
|
||||
return (ctx || document).querySelector(selector)
|
||||
}
|
||||
|
||||
// returns [fileName, fileExt]
|
||||
function getFileNameAndExtension (fullFileName) {
|
||||
var re = /(?:\.([^.]+))?$/
|
||||
var fileExt = re.exec(fullFileName)[1]
|
||||
var fileName = fullFileName.replace('.' + fileExt, '')
|
||||
return [fileName, fileExt]
|
||||
}
|
||||
|
||||
function truncateString (string, length) {
|
||||
if (string.length > length) {
|
||||
return string.substring(0, length) + '…'
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -131,13 +167,16 @@ function readImage (imgObject, cb) {
|
|||
reader.addEventListener('load', function (ev) {
|
||||
var imgSrcBase64 = ev.target.result
|
||||
var img = new Image()
|
||||
img.onload = function () {
|
||||
return cb(img)
|
||||
}
|
||||
img.addEventListener('load', function () {
|
||||
return cb(null, img)
|
||||
})
|
||||
img.addEventListener('error', function (err) {
|
||||
return cb(err)
|
||||
})
|
||||
img.src = imgSrcBase64
|
||||
})
|
||||
reader.addEventListener('error', function (err) {
|
||||
console.log('FileReader error' + err)
|
||||
console.log('FileReader error ' + err)
|
||||
})
|
||||
reader.readAsDataURL(imgObject)
|
||||
}
|
||||
|
|
@ -148,6 +187,19 @@ function getProportionalImageHeight (img, newWidth) {
|
|||
return newHeight
|
||||
}
|
||||
|
||||
function getFileType (file) {
|
||||
// if (file.type) {
|
||||
// const fileType = file.type.split('/')
|
||||
// return fileType
|
||||
// }
|
||||
// const fileExtension = getFileNameAndExtension(file.name)[1]
|
||||
// return fileExtension
|
||||
if (file.type) {
|
||||
return file.type
|
||||
}
|
||||
return mime.lookup(file.name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes an image to specified width and height, using canvas
|
||||
* See https://davidwalsh.name/resize-image-canvas
|
||||
|
|
@ -167,11 +219,12 @@ function resizeImage (img, width, height) {
|
|||
canvas.height = height
|
||||
|
||||
// draw source image into the off-screen canvas:
|
||||
// ctx.clearRect(0, 0, width, height)
|
||||
ctx.drawImage(img, 0, 0, width, height)
|
||||
|
||||
// encode image to data-uri with base64 version of compressed image
|
||||
// canvas.toDataURL('image/jpeg', quality); // quality = [0.0, 1.0]
|
||||
return canvas.toDataURL()
|
||||
return canvas.toDataURL('image/jpeg', 0.7)
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
@ -182,10 +235,14 @@ export default {
|
|||
every,
|
||||
flatten,
|
||||
groupBy,
|
||||
qsa,
|
||||
$,
|
||||
$$,
|
||||
extend,
|
||||
readImage,
|
||||
resizeImage,
|
||||
getProportionalImageHeight,
|
||||
isTouchDevice
|
||||
isTouchDevice,
|
||||
getFileNameAndExtension,
|
||||
truncateString,
|
||||
getFileType
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,62 @@
|
|||
import html from 'yo-yo'
|
||||
import { fileIcon, checkIcon, removeIcon } from './icons'
|
||||
import Utils from '../../core/Utils'
|
||||
import { checkIcon, removeIcon, iconText, iconFile, iconAudio } from './icons'
|
||||
|
||||
function getIconByMime (fileTypeGeneral) {
|
||||
switch (fileTypeGeneral) {
|
||||
case 'text':
|
||||
return iconText()
|
||||
case 'audio':
|
||||
return iconAudio()
|
||||
default:
|
||||
return iconFile()
|
||||
}
|
||||
}
|
||||
|
||||
export default function fileItem (bus, file) {
|
||||
const isUploaded = file.progress === 100
|
||||
const uploadInProgress = file.progress > 0 && file.progress < 100
|
||||
|
||||
const remove = (ev) => {
|
||||
bus.emit('file-remove', file.id)
|
||||
function remove (ev) {
|
||||
const el = document.querySelector(`#${file.id}`)
|
||||
el.classList.add('UppyAnimation-zoomOutLeft')
|
||||
|
||||
// this seems to be working in latest Chrome, Firefox and Safari,
|
||||
// but might not be 100% cross-browser, needs testing
|
||||
// https://davidwalsh.name/css-animation-callback
|
||||
el.addEventListener('animationend', () => {
|
||||
bus.emit('file-remove', file.id)
|
||||
})
|
||||
// bus.emit('file-remove', file.id)
|
||||
}
|
||||
|
||||
const truncatedFileName = Utils.truncateString(file.name, 30)
|
||||
|
||||
// <h5 class="UppyDashboardItem-previewType">${file.extension ? '.' + file.extension : '?'}</h5>
|
||||
|
||||
return html`<li class="UppyDashboardItem"
|
||||
id="${file.id}"
|
||||
title="${file.name}">
|
||||
<div class="UppyDashboardItem-icon">
|
||||
${file.type.general === 'image' ? file.previewEl : fileIcon(file.type)}
|
||||
</div>
|
||||
<h4 class="UppyDashboardItem-name">
|
||||
${file.uploadURL
|
||||
? html`<a href="${file.uploadURL}" target="_blank">${file.name}</a>`
|
||||
: html`<span>${file.name}</span>`
|
||||
}
|
||||
<br>
|
||||
</h4>
|
||||
<div class="UppyDashboardItem-status">
|
||||
<div class="UppyDashboardItem-statusSize">${file.totalSize}</div>
|
||||
${uploadInProgress ? 'Uploading… ' + file.progress + '%' : ''}
|
||||
${isUploaded ? 'Completed' : ''}
|
||||
<div class="UppyDashboardItem-preview">
|
||||
${file.previewEl
|
||||
? file.previewEl
|
||||
: html`<div class="UppyDashboardItem-previewIcon">${getIconByMime(file.type.general)}</div>`
|
||||
}
|
||||
<div class="UppyDashboardItem-progress ${uploadInProgress ? 'is-active' : ''}">
|
||||
<div class="UppyDashboardItem-progressNum">${file.progress}%</div>
|
||||
<div class="UppyDashboardItem-progressInner" style="width: ${file.progress}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="UppyDashboardItem-info">
|
||||
<h4 class="UppyDashboardItem-name">
|
||||
${file.uploadURL
|
||||
? html`<a href="${file.uploadURL}" target="_blank">${truncatedFileName}</a>`
|
||||
: truncatedFileName
|
||||
}
|
||||
</h4>
|
||||
<div class="UppyDashboardItem-status">
|
||||
<span class="UppyDashboardItem-statusSize">${file.totalSize}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="UppyDashboardItem-action">
|
||||
${isUploaded
|
||||
|
|
@ -37,8 +68,5 @@ export default function fileItem (bus, file) {
|
|||
</button>`
|
||||
}
|
||||
</div>
|
||||
<div class="UppyDashboardItem-progress ${uploadInProgress ? 'is-active' : ''}">
|
||||
<div class="UppyDashboardItem-progressInner" style="width: ${file.progress}%"></div>
|
||||
</div>
|
||||
</li>`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ export default class Modal extends Plugin {
|
|||
<div class="UppyModalContent-bar">
|
||||
<h2 class="UppyModalContent-title">Import From ${target.name}</h2>
|
||||
<button class="UppyModalContent-back"
|
||||
onclick=${this.hideAllPanels}>Back</button>
|
||||
onclick=${this.hideAllPanels}>Done</button>
|
||||
</div>
|
||||
${target.render(state)}
|
||||
</div>`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue