fipamo/public/assets/scripts/dash/app/ui/FileManager.js
ro b9b04f1ab2
page api rewire, pt 1
start building out the new version of the page editing api while making
some changes to the original scripts for added flexibility and using the
full range of HTTP methods that weren't being used before.

currenlty, it's just an end to end test to make sure the plumbing works
as it should data is being passed and can be processed.

now that it all works, the guts of page editing can be completed

update sortablejs to the latest since it's been awhile and got rid of
the old version
2024-03-07 15:42:11 -06:00

307 lines
8.6 KiB
JavaScript

import Sortable from '../vendor/sortable.core.esm.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 = '';
//change file order this and chance data-source to data-id
//console.log('ORDER', this.mediaSort.toArray());
for (var i = 0, length = this.imageList.childNodes.length; i < length; i++) {
try {
let div = this.imageList.childNodes[i];
imgList = imgList + div.getAttribute('data-source') + ',';
} catch (e) {
//something is function
}
}
for (var i = 0, length = this.fileList.childNodes.length; i < length; i++) {
try {
let div = this.fileList.childNodes[i];
fileList = fileList + div.getAttribute('data-source') + ',';
} catch (e) {
//something is function
}
}
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;
}
}
}