Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ coverage
*.log
.DS_Store
lib/
.idea
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,26 @@ you can customise file input, preview, error and success messages base on your d
AWS_SECRET_ACCESS_KEY:'xxxxxxx',
AWS_DEFAULT_REGION:'xxxxxxx',
AWS_BUCKET:'xxxxxxx',
}
}
```
2) Now, import upload class and initialize:
```js
import Upload from 'quick-file-uploader'
import Upload from 'quick-file-uploader'
new Upload({storage: 's3'});

### Upload file on server through api

1) define s3 credentials before initialize
```js
window.credentials = {
UPLOAD_URL: 'xxxxxxx'
}
```
2) Now, import upload class and initialize:
```js
import Upload from 'quick-file-uploader'
new Upload({storage: 'api', headers: {'Authorization': 'TOKEN'}});

## License

[MIT license](https://opensource.org/licenses/MIT).
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
"build": "webpack",
"pack": "zip -r quick-file-uploader.zip src/ package.json LICENSE README.md"
},
"keywords": [
"s3",
Expand All @@ -16,7 +17,8 @@
"author": "Umer Ali Chishti <umeralichishti06@gmail.com>",
"license": "MIT",
"dependencies": {
"aws-sdk": "^2.1240.0"
"aws-sdk": "^2.1240.0",
"axios": "^1.1.3"
},
"devDependencies": {
"babel-loader": "^9.0.0",
Expand Down
42 changes: 42 additions & 0 deletions src/adapters/Api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import axios from "axios";

class Api {
constructor(config) {
this.config = config
this.url = credentials.UPLOAD_URL;
}

async file(file, fileNumber, object) {
let fileName = (new Date).getTime() + '-' + file.name;
const formData = new FormData();
formData.append("file", file);
try {
const res = await axios.post(this.url, formData, {
onUploadProgress: (progress) => this.handleProgress(object, fileNumber, progress),
headers: {
'Content-Type': 'multipart/form-data',
...this.config.headers
}
});
const src = res.data.url;
object.addInput(fileName, fileNumber);
object.config.preview(src, object.getFileType(file), fileNumber)
object.config.success(['Successfully uploaded file.'], fileNumber);
return true;
} catch (err) {
if (err) {
object.config.error(['There was an error uploading your file: ' + err], fileNumber);
return false;
}
}

}

handleProgress(object, fileNumber, progress) {
object.uploadProgress[fileNumber] = Math.round(progress.loaded / progress.total * 100);
object.config.progress(object.uploadProgress[fileNumber], fileNumber);
}

}

export default Api;
17 changes: 17 additions & 0 deletions src/adapters/Local.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Local {
file(file, fileNumber, object) {
const reader = new FileReader();
reader.onload = function (e) {
object.preview(e.target.result, this.getFileType(file), fileNumber);
};
reader.onprogress = function (e) {
this.uploadProgress[fileNumber] = Math.round((e.loaded * 100) / e.total);
object.progress(this.uploadProgress[fileNumber], fileNumber);
};
reader.readAsDataURL(file);
return true;
}

}

export default Local;
11 changes: 6 additions & 5 deletions src/s3Upload.js → src/adapters/S3.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import S3 from 'aws-sdk/clients/s3';
import S3sdk from 'aws-sdk/clients/s3';

class S3Upload {
class S3 {
constructor() {
this.bucket = new S3({
this.bucket = new S3sdk({
accessKeyId: credentials.AWS_ACCESS_KEY_ID,
secretAccessKey: credentials.AWS_SECRET_ACCESS_KEY,
region: credentials.AWS_DEFAULT_REGION,
Expand All @@ -18,7 +18,7 @@ class S3Upload {
ACL: 'public-read',
ContentType: file.type
}
return this.bucket.upload(params, function(err, data) {
this.bucket.upload(params, function(err, data) {
if (err) {
object.config.error(['There was an error uploading your file: '+err], fileNumber);
return false;
Expand All @@ -33,7 +33,8 @@ class S3Upload {
object.config.progress(object.uploadProgress[fileNumber], fileNumber);
console.log(object.uploadProgress[fileNumber], fileNumber);
})
return true;
}

}
export default S3Upload;
export default S3;
117 changes: 70 additions & 47 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import S3UPLOAD from './s3Upload.js';
import './style.css';
import Api from './adapters/Api.js';
import Local from './adapters/Local.js';
import S3 from './adapters/S3.js';


class Upload {
Expand All @@ -16,6 +18,7 @@ class Upload {
return false;
}
this.config.storage = config.storage || 'local'
this.config.headers = config.headers || {}
this.config.preview = config.preview || this.preview;
this.config.mimeTypes = config['mime-types'] || 'jpg|jpeg|png|pdf|svg|mp4|3gp|mov|avi|wmv';
this.config.accept = config.accept || 'image/*,video/*,application/pdf'
Expand Down Expand Up @@ -50,22 +53,22 @@ class Upload {

events() {
if(this.config.uploadContainer){
let self = this;
let self = this;
this.config.uploadContainer.addEventListener('click', function(){
document.getElementById(self.BrowseID).click();
});
if(this.config.draggable){
this.config.uploadContainer.addEventListener("dragover", (event)=>{
event.preventDefault();
this.config.uploadContainer.dataset.dragged = true;
this.config.onDrag();
event.preventDefault();
this.config.uploadContainer.dataset.dragged = true;
this.config.onDrag();
});
this.config.uploadContainer.addEventListener("dragleave", ()=>{
this.config.uploadContainer.dataset.dragged = '';
this.config.uploadContainer.removeAttribute('data-dragged');
this.config.onDrop();
this.config.uploadContainer.dataset.dragged = '';
this.config.uploadContainer.removeAttribute('data-dragged');
this.config.onDrop();
});
this.config.uploadContainer.addEventListener("drop", this.uploaderElClick.bind(this));
this.config.uploadContainer.addEventListener("drop", this.uploaderElClick.bind(this));
}
}
}
Expand All @@ -78,13 +81,13 @@ class Upload {
a.dataset.id = i
a.href = "javascript:;"
a.addEventListener("click", this.removePoster.bind(this))
if(type == 'image'){
if(type === 'image'){
const img = document.createElement('img')
img.src = src
img.classList.add('poster-image')
div.appendChild(img);
}
if(type == 'video'){
if(type === 'video'){
const video = document.createElement('video')
video.controls = true;
video.classList.add('poster-video')
Expand All @@ -95,7 +98,7 @@ class Upload {
video.load();
// video.play();
}
if(type == 'application/pdf'){
if(type === 'application/pdf'){
const link = document.createElement('a')
link.src = src
link.innerText = 'PDF File'
Expand Down Expand Up @@ -161,24 +164,24 @@ class Upload {
}

getFileType(file) {
if(file.type.match('image.*')){
return 'image'
}
if(file.type.match('video.*')){
return 'video';
}
if(file.type.match('audio.*')){
return 'audio';
}
return file.type;
if(file.type.match('image.*')){
return 'image'
}
if(file.type.match('video.*')){
return 'video';
}
if(file.type.match('audio.*')){
return 'audio';
}
return file.type;
}

randerContainer(){
let hiddenInput = '';
let previewContainer = '';
let multiple = (this.config.multiple)? 'multiple' :'';
let localInputName = 'name='+this.config.hiddenInputName;
if(this.config.storage == 's3'){
if(this.config.storage === 's3' || this.config.storage === 'api'){
if(!this.config.multiple){
let editInput = document.querySelector('input[name="'+this.config.hiddenInputName+'"]')
let editValue = (editInput)? editInput.value :'';
Expand All @@ -200,6 +203,8 @@ class Upload {

addInput(value, fileNumber){
if(!this.config.multiple){
console.log(this.config);
console.log(this.config.hiddenInputName);
document.querySelector('input[name="'+this.config.hiddenInputName+'"]').value = value;
return true;
}
Expand All @@ -208,57 +213,75 @@ class Upload {
'<input type="hidden" id="file__'+fileNumber+'" name='+this.config.hiddenInputName+' value="'+value+'">'
);
}

uploaderElClick(event){
event.preventDefault();
let self = event.target;
this.files = self.files || event.dataTransfer.files;
this.files = self.files || event.dataTransfer.files;
if(this.config.uploadContainer.dataset.dragged){
this.config.uploadContainer.dataset.dragged = '';
this.config.uploadContainer.removeAttribute('data-dragged');
self = document.getElementById(this.BrowseID);
self = document.getElementById(this.BrowseID);
}
([...this.files]).forEach((obj,i) => {
([...this.files]).forEach(async (obj,i) => {
let number = this.dT.items.length;
if(this.uploadFile(obj, number)){
if(await this.uploadFile(obj, number)){
this.dT.items.add(obj)
}
});
self.files = this.dT.files
}
uploadFile(file, fileNumber){
async uploadFile(file, fileNumber) {
let $this = this
let hasError = false;
let errors = [];
let regex = new RegExp("(.*?)\.("+this.config.mimeTypes+")$");
let regex = new RegExp("(.*?)\.(" + this.config.mimeTypes + ")$");
if (!(regex.test(file.name))) {
hasError = true;
errors.push('Allowed file type are '+this.config.mimeTypes.split('|').join(', '));
errors.push('Allowed file type are ' + this.config.mimeTypes.split('|').join(', '));
}
if(file.size > this.config.size){
if (file.size > this.config.size) {
hasError = true;
errors.push('File size should not be greater than '+ this.formatBytes(this.config.size));
errors.push('File size should not be greater than ' + this.formatBytes(this.config.size));
}
if(hasError){
if (hasError) {
this.config.error(errors, fileNumber);
return false;
}
this.uploadProgress.push(0);
if(this.config.storage == 's3'){
new S3UPLOAD().file(file, fileNumber, this);
const adapters = {
's3': S3,
'api': Api,
'local': Local
};

const selectedAdapter = adapters[this.config.storage];
if (selectedAdapter === undefined) {
errors.push('No adapter found for your storage system' + this.config.storage);
this.config.error(errors, fileNumber)
return false;
}
if(this.config.storage == 'local'){
const reader = new FileReader();
reader.onload = function (e) {
$this.config.preview(e.target.result, $this.getFileType(file), fileNumber);
};
reader.onprogress = function (e) {
$this.uploadProgress[fileNumber] = Math.round((e.loaded * 100) / e.total);
$this.config.progress($this.uploadProgress[fileNumber], fileNumber);
};
reader.readAsDataURL(file);

return await (new selectedAdapter(this.config)).file(file, fileNumber, this);
}

static async customUpload(file, fileNumber, object) {
let errors = [];

const adapters = {
's3': S3,
'api': Api,
'local': Local
};

const selectedAdapter = adapters[object.storage];
if (selectedAdapter === undefined) {
errors.push('No adapter found for your storage system' + this.config.storage);
object.error(errors, fileNumber)
return false;
}
return true;

return await (new selectedAdapter()).file(file, fileNumber, object);
}

}
Expand Down