Composer package dependencies hadn't been updated in awhile, so a part of the clean up for the php 8.1 install, that has been handled Moment was being used to handle date formatting but it hasn't been updated in awhile either, so I switched to Carbon which is still in active development.
265 lines
7.3 KiB
JavaScript
265 lines
7.3 KiB
JavaScript
import Sortable from 'sortablejs';
|
|
import DataUtils from '../utils/DataUtils';
|
|
import Notfications from './Notifications.js';
|
|
const notify = new Notfications();
|
|
|
|
export default class FileManager {
|
|
//--------------------------
|
|
// constructor
|
|
//--------------------------
|
|
constructor(upload, input, imageList, fileList) {
|
|
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
|
|
);
|
|
}
|
|
}
|
|
getFiles() {
|
|
return this.files;
|
|
}
|
|
|
|
reindexFiles(sortOrder, step) {
|
|
let count = sortOrder.length;
|
|
if (step == 0) this.files = [];
|
|
var utils = new DataUtils();
|
|
utils.imgLoad(sortOrder[step].earl).then(blob => {
|
|
var fresh = new File([blob], sortOrder[step].fileName, { type: blob.type });
|
|
this.files.push(fresh);
|
|
var limit = count - 1;
|
|
if (this.files.length <= limit) {
|
|
step = step + 1;
|
|
this.reindexFiles(sortOrder, step);
|
|
} else {
|
|
notify.alert('FILES READY TO UPLOAD', true);
|
|
}
|
|
});
|
|
}
|
|
|
|
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');
|
|
remove.className = 'media-remove';
|
|
remove.innerHTML = 'X';
|
|
remove.addEventListener(
|
|
'click',
|
|
e => self.removeFile(e, 'media'),
|
|
false
|
|
);
|
|
//get counts for lists
|
|
var mediaCount = self.imageList.childNodes.length;
|
|
var fileCount = self.fileList.childNodes.length;
|
|
// sort files
|
|
switch (theFile.type) {
|
|
case 'image/jpg':
|
|
case 'image/jpeg':
|
|
case 'image/gif':
|
|
case 'image/svg':
|
|
case 'image/png':
|
|
//create element and add to list
|
|
//var image = document.createElement('img');
|
|
//image.src = f.target.result;
|
|
//image.title = escape(theFile.name);
|
|
var span = document.createElement('div');
|
|
span.style.background =
|
|
'url(' +
|
|
f.target.result +
|
|
') no-repeat center center / cover';
|
|
span.className = 'img-item';
|
|
|
|
//image.setAttribute('id', i);
|
|
self.storage.push([
|
|
{
|
|
id: 'page_image' + i,
|
|
data: f.target.result,
|
|
type: theFile.type,
|
|
name: escape(theFile.name)
|
|
}
|
|
]);
|
|
if (mediaCount < 0) mediaCount = 0;
|
|
span.setAttribute('id', mediaCount);
|
|
remove.setAttribute('id', mediaCount);
|
|
span.setAttribute('data-file-name', theFile.name);
|
|
span.appendChild(remove);
|
|
self.imageList.appendChild(span);
|
|
|
|
break;
|
|
case 'video/mp4':
|
|
var video = document.createElement('div');
|
|
video.className = 'video-item';
|
|
video.setAttribute('data-source', f.target.result);
|
|
if (mediaCount < 0) mediaCount = 0;
|
|
video.setAttribute('id', mediaCount);
|
|
remove.setAttribute('id', mediaCount);
|
|
video.setAttribute('data-file-name', theFile.name);
|
|
video.appendChild(remove);
|
|
self.imageList.appendChild(video);
|
|
break;
|
|
case 'audio/mpeg':
|
|
var sound = document.createElement('div');
|
|
sound.className = 'audio-item';
|
|
sound.setAttribute('data-source', f.target.result);
|
|
sound.setAttribute('id', fileCount);
|
|
remove.setAttribute('id', fileCount);
|
|
sound.setAttribute('data-file-name', theFile.name);
|
|
sound.appendChild(remove);
|
|
self.fileList.appendChild(sound);
|
|
break;
|
|
case 'application/pdf':
|
|
case 'text/plain':
|
|
case 'text/rtf':
|
|
var file = document.createElement('div');
|
|
file.className = 'file-item';
|
|
file.setAttribute('data-source', f.target.result);
|
|
file.setAttribute('id', fileCount);
|
|
remove.setAttribute('id', fileCount);
|
|
file.setAttribute('data-file-name', theFile.name);
|
|
file.appendChild(remove);
|
|
self.fileList.appendChild(file);
|
|
break;
|
|
}
|
|
};
|
|
})(file);
|
|
// Read in the image file as a data URL.
|
|
reader.readAsDataURL(file);
|
|
}
|
|
//give the script a beat to add the child nodes, then update it all
|
|
setTimeout(() => {
|
|
self.updateFiles();
|
|
}, 50);
|
|
}
|
|
|
|
//--------------------------
|
|
// event handlers
|
|
//--------------------------
|
|
updateFiles() {
|
|
let currentFiles = []; //store current list
|
|
let items = [];
|
|
//get files from media and files list
|
|
for (let index = 0; index < this.imageList.childNodes.length; index++) {
|
|
items.push(this.imageList.childNodes[index]);
|
|
}
|
|
|
|
for (let index = 0; index < this.fileList.childNodes.length; index++) {
|
|
items.push(this.fileList.childNodes[index]);
|
|
}
|
|
|
|
for (let index = 0; index < items.length; index++) {
|
|
var item = items[index];
|
|
let url = '';
|
|
if (item.className == 'img-item') {
|
|
url = item.style.backgroundImage.slice(4, -1).replace(/"/g, '');
|
|
} else {
|
|
url = item.getAttribute('data-source');
|
|
}
|
|
currentFiles.push({
|
|
earl: url,
|
|
fileName: item.getAttribute('data-file-name')
|
|
});
|
|
}
|
|
this.reindexFiles(currentFiles, 0);
|
|
}
|
|
|
|
removeFile(e) {
|
|
var list = [];
|
|
switch (e.target.parentNode.className) {
|
|
case 'img-item':
|
|
case 'video-item':
|
|
list = this.imageList;
|
|
|
|
break;
|
|
case 'audio-item':
|
|
case 'file-item':
|
|
list = this.fileList;
|
|
break;
|
|
}
|
|
for (let index = 0; index < list.childNodes.length; index++) {
|
|
let media = list.childNodes[index];
|
|
if (media.id == e.target.id) {
|
|
list.removeChild(media);
|
|
notify.alert('REINDEXING MEDIA', null);
|
|
this.updateFiles();
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|