297 lines
8.3 KiB
JavaScript
297 lines
8.3 KiB
JavaScript
|
import Sortable from '../vendor/sortable.js';
|
||
|
import anime from '../vendor/anime.es.js';
|
||
|
import DataUtils from '../utils/DataUtils.js';
|
||
|
import Notfications from './Notifications.js';
|
||
|
import Maintenance from '../controllers/MaintenanceManager.js';
|
||
|
const notify = new Notfications();
|
||
|
|
||
|
export default class FileManager {
|
||
|
//--------------------------
|
||
|
// constructor
|
||
|
//--------------------------
|
||
|
constructor(upload, input, imageList, fileList) {
|
||
|
this.mm = new Maintenance(null, null, document.getElementById('notify-progress'));
|
||
|
this.upload = upload;
|
||
|
this.input = input;
|
||
|
this.imageList = imageList;
|
||
|
this.fileList = fileList;
|
||
|
this.accetableFiles = [
|
||
|
'image/jpeg',
|
||
|
'image/gif',
|
||
|
'image/png',
|
||
|
'image/svg',
|
||
|
'audio/mpeg',
|
||
|
'video/mp4',
|
||
|
'application/pdf',
|
||
|
'text/plain',
|
||
|
'text/rtf'
|
||
|
];
|
||
|
this.files = [];
|
||
|
this.sortedFiles = [];
|
||
|
this.storage = [];
|
||
|
this.mediaSort = Sortable.create(this.imageList, {
|
||
|
animation: 150,
|
||
|
onUpdate: () => {
|
||
|
//notify.alert('REINDEXING MEDIA', null);
|
||
|
//this.updateFiles();
|
||
|
}
|
||
|
});
|
||
|
this.fileSort = Sortable.create(this.fileList, {
|
||
|
animation: 150,
|
||
|
onUpdate: () => {
|
||
|
//notify.alert('REINDEXING FILES', null);
|
||
|
//this.updateFiles();
|
||
|
}
|
||
|
});
|
||
|
this.start();
|
||
|
}
|
||
|
//--------------------------
|
||
|
// methods
|
||
|
//--------------------------
|
||
|
start() {
|
||
|
this.upload.addEventListener('dragover', e => this.handleFileActions(e), false);
|
||
|
this.upload.addEventListener('drop', e => this.handleFileActions(e), false);
|
||
|
this.input.addEventListener('change', e => this.handleFileActions(e), false);
|
||
|
var removeMedia = document.querySelectorAll('.media-remove');
|
||
|
for (var i = 0, length = removeMedia.length; i < length; i++) {
|
||
|
removeMedia[i].addEventListener(
|
||
|
'click',
|
||
|
e => this.removeFile(e, 'media'),
|
||
|
false
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
getFileOrder() {
|
||
|
let imgList = '';
|
||
|
let fileList = '';
|
||
|
for (var i = 0, length = this.imageList.childNodes.length; i < length; i++) {
|
||
|
let div = this.imageList.childNodes[i];
|
||
|
imgList = imgList + div.getAttribute('data-source') + ',';
|
||
|
}
|
||
|
for (var i = 0, length = this.fileList.childNodes.length; i < length; i++) {
|
||
|
let div = this.fileList.childNodes[i];
|
||
|
fileList = fileList + div.getAttribute('data-source') + ',';
|
||
|
}
|
||
|
let media = { images: imgList, files: fileList };
|
||
|
return media;
|
||
|
}
|
||
|
|
||
|
sortFiles(files) {
|
||
|
var self = this;
|
||
|
for (var i = 0, file; (file = files[i]); i++) {
|
||
|
var reader = new FileReader();
|
||
|
// Closure to capture the file information
|
||
|
reader.onload = (theFile => {
|
||
|
return function (f) {
|
||
|
//create remove button object
|
||
|
var remove = document.createElement('button');
|
||
|
var removeIcon = document.createElement('i');
|
||
|
removeIcon.classList.add('ti', 'ti-x');
|
||
|
remove.className = 'media-remove';
|
||
|
remove.appendChild(removeIcon);
|
||
|
//remove.setAttribute('id', mediaCount);
|
||
|
remove.addEventListener(
|
||
|
'click',
|
||
|
e => self.removeFile(e, 'media'),
|
||
|
false
|
||
|
);
|
||
|
|
||
|
//upload the file
|
||
|
let upload = new FormData();
|
||
|
upload.enctype = 'multipart/form-data';
|
||
|
upload.append('upload_files[]', theFile, theFile.name);
|
||
|
let item = null;
|
||
|
let progress = null;
|
||
|
|
||
|
// sort files
|
||
|
switch (theFile.type) {
|
||
|
case 'image/jpg':
|
||
|
case 'image/jpeg':
|
||
|
case 'image/gif':
|
||
|
case 'image/svg':
|
||
|
case 'image/png':
|
||
|
item = self.itemFactory('img-item');
|
||
|
progress = document.getElementById(
|
||
|
'pgs' + item.getAttribute('id')
|
||
|
);
|
||
|
self.mm
|
||
|
.filesUpload(theFile.type, upload, progress)
|
||
|
.then(result => {
|
||
|
item.setAttribute('data-source', result.filePath);
|
||
|
item.style.background =
|
||
|
'url(' +
|
||
|
f.target.result +
|
||
|
') no-repeat center center / cover';
|
||
|
anime({
|
||
|
targets: progress,
|
||
|
width: 0,
|
||
|
easing: 'easeInOutQuint',
|
||
|
duration: 1000,
|
||
|
complete: () => {
|
||
|
item.removeChild(progress);
|
||
|
item.appendChild(remove);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
break;
|
||
|
case 'video/mp4':
|
||
|
item = self.itemFactory('video-item');
|
||
|
progress = document.getElementById(
|
||
|
'pgs' + item.getAttribute('id')
|
||
|
);
|
||
|
self.mm
|
||
|
.filesUpload(theFile.type, upload, progress)
|
||
|
.then(result => {
|
||
|
item.setAttribute('data-source', result.filePath);
|
||
|
let video = document.createElement('video');
|
||
|
let source = document.createElement('source');
|
||
|
source.src = f.target.result;
|
||
|
video.appendChild(source);
|
||
|
item.appendChild(video);
|
||
|
anime({
|
||
|
targets: progress,
|
||
|
width: 0,
|
||
|
easing: 'easeInOutQuint',
|
||
|
duration: 1000,
|
||
|
complete: () => {
|
||
|
item.removeChild(progress);
|
||
|
item.appendChild(remove);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
break;
|
||
|
case 'audio/mpeg':
|
||
|
item = self.itemFactory('audio-item');
|
||
|
progress = document.getElementById(
|
||
|
'pgs' + item.getAttribute('id')
|
||
|
);
|
||
|
self.mm
|
||
|
.filesUpload(theFile.type, upload, progress)
|
||
|
.then(result => {
|
||
|
item.setAttribute('data-source', result.filePath);
|
||
|
let audio = document.createElement('audio');
|
||
|
audio.setAttribute('controls', true);
|
||
|
let source = document.createElement('source');
|
||
|
source.src = f.target.result;
|
||
|
audio.appendChild(source);
|
||
|
item.appendChild(audio);
|
||
|
anime({
|
||
|
targets: progress,
|
||
|
width: 0,
|
||
|
easing: 'easeInOutQuint',
|
||
|
duration: 1000,
|
||
|
complete: () => {
|
||
|
item.removeChild(progress);
|
||
|
item.appendChild(remove);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
break;
|
||
|
case 'application/pdf':
|
||
|
case 'text/plain':
|
||
|
case 'text/rtf':
|
||
|
item = self.itemFactory('file-item');
|
||
|
progress = document.getElementById(
|
||
|
'pgs' + item.getAttribute('id')
|
||
|
);
|
||
|
self.mm
|
||
|
.filesUpload(theFile.type, upload, progress)
|
||
|
.then(result => {
|
||
|
item.setAttribute('data-source', result.filePath);
|
||
|
let link = document.createElement('a');
|
||
|
link.href = result.filePath;
|
||
|
link.innerHTML = result.fileName;
|
||
|
item.appendChild(link);
|
||
|
anime({
|
||
|
targets: progress,
|
||
|
width: 0,
|
||
|
easing: 'easeInOutQuint',
|
||
|
duration: 1000,
|
||
|
complete: () => {
|
||
|
item.removeChild(progress);
|
||
|
item.appendChild(remove);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
break;
|
||
|
}
|
||
|
};
|
||
|
})(file);
|
||
|
// Read in the image file as a data URL.
|
||
|
reader.readAsDataURL(file);
|
||
|
}
|
||
|
}
|
||
|
itemFactory(type = null) {
|
||
|
//get counts for lists
|
||
|
var mediaCount = this.imageList.childNodes.length;
|
||
|
var fileCount = this.fileList.childNodes.length;
|
||
|
if (mediaCount < 0) mediaCount = 0;
|
||
|
if (fileCount < 0) fileCount = 0;
|
||
|
var item = document.createElement('div');
|
||
|
item.className = type;
|
||
|
var progress = document.createElement('div');
|
||
|
progress.className = 'item-progress';
|
||
|
item.appendChild(progress);
|
||
|
|
||
|
if (type == 'img-item' || type == 'video-item') {
|
||
|
this.imageList.appendChild(item);
|
||
|
progress.setAttribute('id', 'pgs' + mediaCount);
|
||
|
item.setAttribute('id', mediaCount);
|
||
|
} else {
|
||
|
this.fileList.appendChild(item);
|
||
|
progress.setAttribute('id', 'pgs' + fileCount);
|
||
|
item.setAttribute('id', fileCount);
|
||
|
}
|
||
|
return item;
|
||
|
}
|
||
|
|
||
|
//--------------------------
|
||
|
// event handlers
|
||
|
//--------------------------
|
||
|
removeFile(e) {
|
||
|
var item = e.target.parentNode.parentNode;
|
||
|
switch (item.className) {
|
||
|
case 'img-item':
|
||
|
case 'video-item':
|
||
|
this.imageList.removeChild(item);
|
||
|
break;
|
||
|
case 'audio-item':
|
||
|
case 'file-item':
|
||
|
this.fileList.removeChild(item);
|
||
|
break;
|
||
|
}
|
||
|
notify.alert('File Removed!', true);
|
||
|
}
|
||
|
|
||
|
handleFileActions(e) {
|
||
|
e.stopPropagation();
|
||
|
e.preventDefault();
|
||
|
let self = this;
|
||
|
let rawList = [];
|
||
|
let sortedList = [];
|
||
|
let notOnTheList = [];
|
||
|
|
||
|
switch (e.type) {
|
||
|
case 'dragover':
|
||
|
e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
||
|
break;
|
||
|
case 'change':
|
||
|
case 'drop':
|
||
|
e.type == 'drop'
|
||
|
? (rawList = e.dataTransfer.files)
|
||
|
: (rawList = e.target.files);
|
||
|
for (var i = 0, f; (f = rawList[i]); i++) {
|
||
|
// check witch files are cool to upload
|
||
|
if (this.accetableFiles.includes(f.type)) {
|
||
|
sortedList.push(f);
|
||
|
} else {
|
||
|
notOnTheList.push(f);
|
||
|
}
|
||
|
}
|
||
|
//send for sorting
|
||
|
self.sortFiles(sortedList);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|