fipamo/public/assets/scripts/dash/app/controllers/PageEditor.js
ro 714485c6a6
cleaned up meta ui, made editor display contextual
there were some nagging space issues in the new meta ui layout, so those
were addressed. it'll will probably change a billion more times, but
it's starting from a solid place

the text editor ui now only display when text is selected and goes away
after an operation has been completed or when text is deselected, making
the overall page editing experience streamlined
2025-05-12 14:58:32 -06:00

267 lines
7.5 KiB
JavaScript

//TOOLS
import ContentRequest, {
TASK_PAGE_CREATE,
TASK_PAGE_EDIT,
TASK_PAGE_DELETE
} from '../../libraries/ContentRequest.js';
import Maintenance from '../../libraries/MaintenanceRequest.js';
import * as DataEvent from '../events/DataEvent.js';
import PageActions from '../actions/PageActions.js';
import * as EditorEvent from '../events/EditorEvent.js';
import TextEditor from '../ui/TextEditor.js';
import Notfications from '../ui/Notifications.js';
import FileManager from '../ui/FileManager.js';
const notify = new Notfications();
export default class PostEditor {
//--------------------------
// constructor
//--------------------------
constructor() {
this.processing = false;
this.textSelected = false;
let self = this;
this.cr = new ContentRequest(null, document.getElementById('notify-progress'));
this.mr = new Maintenance(null, null);
this.urlPieces = document.URL.split('/');
this.post = [];
this.postID = null;
this.postUUID = null;
this.postLayout = null;
this.fm = null;
if (document.querySelector('.file-manager').getAttribute('data-index')) {
this.postID = document
.querySelector('.file-manager')
.getAttribute('data-index');
this.postUUID = document
.querySelector('.file-manager')
.getAttribute('data-uuid');
this.postLayout = document
.querySelector('.file-manager')
.getAttribute('data-layout');
}
let textEdit = document.getElementById('edit');
let control = document.querySelector('.text-editor-control');
textEdit.addEventListener('select', e => {
if (!self.textSelected) {
self.textSelected = true;
control.classList.remove('hide-el');
control.classList.add('show-grid');
}
});
textEdit.addEventListener('click', e => {
if (self.textSelected) {
self.textSelected = false;
control.classList.add('hide-el');
control.classList.remove('show-grid');
}
});
textEdit.addEventListener('blur', e => {
if (self.textSelected) {
self.textSelected = false;
control.classList.add('hide-el');
control.classList.remove('show-grid');
}
});
if (document.getElementById('edit')) {
this.editor = new TextEditor(
document.getElementById('edit'),
document.querySelector('.page-meta').offsetHeight +
document.querySelector('.file-manager').offsetHeight +
document.querySelector('.text-editor').offsetHeight
);
this.editor.addListener(
EditorEvent.EDITOR_DELETE,
() => this.handleEditorOptions(EditorEvent.EDITOR_DELETE),
false
);
this.editor.addListener(
EditorEvent.EDITOR_UPLOAD_POST_IMAGE,
() => this.handleEditorOptions(EditorEvent.EDITOR_UPLOAD_POST_IMAGE),
false
);
this.editor.addListener(
EditorEvent.EDITOR_UPDATE,
() => this.handleEditorOptions(EditorEvent.EDITOR_UPDATE),
false
);
this.editor.addListener(
EditorEvent.EDITOR_SAVE,
() => this.handleEditorOptions(EditorEvent.EDITOR_SAVE),
false
);
document.getElementById('post-image-upload').addEventListener(
'change',
e => {
this.handleImageUpload(e.target.id, e.target.files);
},
false
);
/*
TinyDatePicker(document.getElementById('post-date'), {
mode: 'dp-below',
format() {
//return self.dateUtils.getDate('origin', date);
}
});
*/
this.start();
}
}
//--------------------------
// methods
//--------------------------
start() {
if (document.querySelector('.file-drop')) {
//insert fileManager here
this.fm = new FileManager(
document.querySelector('.file-drop'),
document.getElementById('page-files-upload'),
document.getElementById('page-images-list'),
document.querySelector('.page-files-list')
);
var optionButtons = document.querySelectorAll('.post-option-btn');
for (var i = 0, length = optionButtons.length; i < length; i++) {
optionButtons[i].addEventListener(
'click',
e => this.handlePostOptions(e),
false
);
}
}
let metabtn = document.getElementById('meta-info-toggle');
let meta = document.querySelector('.meta');
metabtn.addEventListener('click', e => {
let metaO = window.getComputedStyle(meta).getPropertyValue('opacity');
if (metaO == 0) {
meta.classList.remove('hide-el');
meta.classList.add('show-grid');
} else {
meta.classList.add('hide-el');
meta.classList.remove('show-grid');
}
});
}
//--------------------------
// event handlers
//--------------------------
handlePostOptions(e) {
let currentOption = null;
switch (e.target.id) {
case 'option-page-icon':
case 'option-menu-pin':
currentOption = document.getElementById('option-menu-pin');
break;
case 'option-feature-icon':
case 'option-feature':
currentOption = document.getElementById('option-feature');
break;
case 'option-published-icon':
case 'option-published':
currentOption = document.getElementById('option-published');
break;
}
if (currentOption != null) {
let active = currentOption.getAttribute('data-active');
active == 'false'
? currentOption.setAttribute('data-active', 'true')
: currentOption.setAttribute('data-active', 'false');
}
}
handleEditorOptions(e) {
if (this.processing) return;
let self = this;
switch (e) {
case EditorEvent.EDITOR_SAVE:
case EditorEvent.EDITOR_UPDATE:
var task = '';
e === EditorEvent.EDITOR_SAVE
? (task = TASK_PAGE_CREATE)
: (task = TASK_PAGE_EDIT);
new PageActions().collectInfo(this.fm.getFileOrder()).then(page => {
self.processing = true;
notify.alert('Writing down changes', null);
self.cr
.pageActions(task, page)
.then(r => {
self.processing = false;
if (
r.type === DataEvent.PAGE_ERROR ||
r.type === DataEvent.API_REQUEST_LAME
) {
notify.alert(r.message, false);
} else {
if (r.type === DataEvent.PAGE_UPDATED) {
notify.alert(r.message, true);
} else {
notify.alert(r.message, true);
window.location = '/dashboard/page/edit/' + r.id;
}
}
})
.catch(err => {
self.processing = false;
notify.alert(err, false);
});
});
break;
case EditorEvent.EDITOR_DELETE:
if (this.postLayout === 'index') {
notify.alert('Index cannot be deleted', false);
return;
}
if (confirm("AYE! You know you're deleting this post, right?")) {
new PageActions()
.collectInfo(this.fm.getFileOrder())
.then(page => {
self.processing = true;
this.cr
.pageActions(TASK_PAGE_DELETE, page)
.then(() => {
self.processing = false;
window.location = '/dashboard/pages';
})
.catch(err => {
self.processing = false;
notify.alert(err, false);
});
})
.catch(() => {});
} else {
// Do nothing!
}
break;
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE:
document.getElementById('post-image-upload').click();
break;
}
}
handleImageUpload(type, files) {
let self = this;
notify.alert('Uploading Image', null);
let upload = new FormData();
upload.enctype = 'multipart/form-data';
upload.append('upload_files[]', files[0], files[0].name);
this.mr
.filesUpload(files[0].type, upload)
.then(result => {
if (result.message == 'File Uploaded. Great!') {
self.editor.notify(
EditorEvent.EDITOR_UPLOAD_POST_IMAGE,
result.filePath
);
notify.alert('Image Added to Entry', true);
} else {
notify.alert('Uh oh. Image not added', false);
}
})
.catch(() => {
notify.alert('Uh oh. Image not added', false);
});
}
}