fipamo/public/assets/scripts/dash/app/ui/FileManager.js
ro 1e37580869
added front end scripting to recreate API
dropped in js from the old site to begin the process of wiring up the
API, but this time around, scripts will be served directly in browswer
rather than being transpiled through NPM/Babel, eliminating the need for
NPM.

also scripting will new modularized and served specifically for the
requirements of the page loading it. no more front loading everything.
only script that is needed for that page will be retrieved. if no
scripting is needed, none will be loaded.

The only casualty so far has been syntax highlighting due to prismjs
still being a common js module, but either this will be replaced with
another library or a custom syntax enginge will be created at a later
date
2024-03-06 11:53:40 -06:00

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;
}
}
}