Compare commits
67 commits
Author | SHA1 | Date | |
---|---|---|---|
|
62e2dea287 | ||
|
8ce253418d | ||
|
8622ba5941 | ||
|
302362a478 | ||
|
c2b3b234fa | ||
|
fce378d437 | ||
|
69fc689d38 | ||
|
c546aa7b63 | ||
|
6f2a8cfb4b | ||
|
614c9859b1 | ||
|
0ee4083949 | ||
|
d92944b2ec | ||
|
c004452c55 | ||
|
7cefc12692 | ||
|
2d5de69f1c | ||
|
f6aac33ae4 | ||
|
c98a75f931 | ||
|
257d2a0623 | ||
|
59e0f37b3e | ||
|
32a4f32202 | ||
|
0e52528de0 | ||
|
6c053868a2 | ||
|
dc08f60098 | ||
|
8502c4f0e0 | ||
|
2fdd7f40f0 | ||
|
de2aec58c9 | ||
|
55b16a0acd | ||
|
39c6ff7f11 | ||
|
1b66f5daf9 | ||
|
e5873b92cf | ||
|
4151891129 | ||
|
4f4ee5dfc7 | ||
|
cecead05a1 | ||
|
815ebf58f7 | ||
|
a475b64aca | ||
|
ccf65e1899 | ||
|
6e9368c2aa | ||
|
854cf12067 | ||
|
85a7eab8be | ||
|
bf383785a0 | ||
|
b1c884689e | ||
|
ce30f3efb7 | ||
|
fe8a5e4e96 | ||
|
da49388caa | ||
|
3c3f2a0881 | ||
|
3968e32e78 | ||
|
7d80e42642 | ||
|
7f3be4c0c5 | ||
|
8355137952 | ||
|
02563a4c87 | ||
|
46691b454d | ||
|
321903643a | ||
|
8f5df10b89 | ||
|
3d8c421f76 | ||
|
6b2ee8e401 | ||
|
3706a81c5f | ||
|
c21704b8bd | ||
|
18e67691f5 | ||
|
005de8027e | ||
|
913dd3a57f | ||
|
1c7fcd6664 | ||
|
3b118782ef | ||
|
b4ed326387 | ||
|
a5f2f17670 | ||
|
e80408dcb0 | ||
|
573219472a | ||
|
00f9229eb2 |
24 changed files with 16 additions and 2318 deletions
15
.gitignore
vendored
15
.gitignore
vendored
|
@ -15,8 +15,18 @@ public/assets/css/*
|
||||||
!public/assets/css/dash
|
!public/assets/css/dash
|
||||||
!public/assets/scripts
|
!public/assets/scripts
|
||||||
public/assets/scripts/*
|
public/assets/scripts/*
|
||||||
|
<<<<<<< HEAD
|
||||||
|
!public/assets/scripts/Start.js
|
||||||
|
/public/assets/images/global/rikc-logo.svg
|
||||||
|
|
||||||
|
|
||||||
|
=======
|
||||||
!public/assets/scripts/dash.js
|
!public/assets/scripts/dash.js
|
||||||
|
<<<<<<< HEAD
|
||||||
|
>>>>>>> develop
|
||||||
|
=======
|
||||||
!public/assets/scripts/dash.js.map
|
!public/assets/scripts/dash.js.map
|
||||||
|
>>>>>>> develop
|
||||||
!public/assets/images
|
!public/assets/images
|
||||||
public/assets/images/*
|
public/assets/images/*
|
||||||
!public/assets/images/global/
|
!public/assets/images/global/
|
||||||
|
@ -41,3 +51,8 @@ config/tags.json
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
config.codekit3
|
config.codekit3
|
||||||
/config/backups
|
/config/backups
|
||||||
|
|
||||||
|
src/com/*
|
||||||
|
src/styles/*
|
||||||
|
|
||||||
|
src/com/ui/TextEditor.js
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
<svg width="305" height="305" viewBox="0 0 305 305" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<g id="Group">
|
|
||||||
<path id="Path" fill="none" stroke="#894262" stroke-width="30" stroke-linecap="round" stroke-linejoin="round" d="M 289.203003 152.102005 C 289.203003 227.82077 227.820801 289.203003 152.10199 289.203003 C 76.383202 289.203003 15.001002 227.82077 15.001002 152.102005 C 15.001002 76.383209 76.383202 15.001007 152.10199 15.001007 C 227.820801 15.001007 289.203003 76.383209 289.203003 152.102005 Z"/>
|
|
||||||
</g>
|
|
||||||
<g id="g1">
|
|
||||||
<g id="g2">
|
|
||||||
<path id="path1" fill="#894262" stroke="none" d="M 184.531082 78.841095 C 186.322433 78.841095 188.113785 79.097 189.649246 79.352905 C 190.928772 79.60881 192.208313 80.376541 192.976044 81.656067 C 193.99968 82.935608 194.51149 85.49469 194.51149 88.565598 L 194.51149 97.522369 C 194.51149 99.313721 194.51149 101.616898 194.767395 103.920074 C 194.767395 106.223251 194.51149 108.270508 193.743759 109.550049 C 192.976044 110.82959 192.208313 111.597305 190.928772 111.85321 C 189.649246 112.109131 188.113785 112.365036 186.578339 112.365036 C 184.786987 112.365036 183.251541 112.365036 181.460175 112.109131 C 179.668823 111.85321 177.877472 112.109131 176.342026 112.365036 C 175.062485 112.620941 174.038849 112.876846 172.759308 112.876846 C 171.479767 113.132751 170.456131 113.388672 169.432495 113.644577 C 166.617523 114.412308 164.058426 115.691849 161.243454 117.22728 C 158.428467 119.018646 156.381195 120.809998 154.845749 122.857269 C 154.078018 124.13681 153.054398 125.672256 152.286667 126.951797 C 151.263031 128.487244 150.23941 130.02269 149.47168 131.558136 C 148.959869 132.837677 148.448044 134.373123 148.192139 135.652664 C 147.680328 137.18811 147.168503 138.723557 146.912598 140.003098 C 146.656693 141.282639 146.400787 142.306274 146.400787 143.585815 C 146.400787 144.865356 146.144882 146.144897 145.888962 147.424423 C 145.633057 148.192154 145.633057 148.703964 145.888962 149.21579 C 145.888962 149.983521 145.888962 150.495331 145.633057 151.007141 L 145.633057 155.101669 C 145.377151 156.38121 145.121246 157.660751 145.377151 158.940292 C 145.633057 160.475739 145.633057 162.011185 145.633057 163.290726 L 145.633057 201.421021 C 145.633057 203.724182 145.633057 205.771454 145.377151 207.562805 C 145.121246 209.354156 144.609421 210.889618 143.841705 212.169159 C 143.5858 212.680969 143.073975 212.93689 142.306259 213.19278 C 141.538528 213.4487 140.514893 213.704605 139.747177 213.96051 L 138.467636 213.96051 C 137.699921 214.216415 136.676285 214.216415 135.652649 214.216415 L 121.833618 214.216415 C 120.809982 213.96051 119.786354 213.96051 118.762718 213.96051 L 115.180008 213.96051 C 114.412285 213.704605 113.388649 213.19278 112.620926 212.93689 C 111.853203 212.680969 111.08548 212.169159 110.829575 211.401428 C 110.061852 210.633698 109.805939 209.354156 109.805939 207.562805 C 109.550034 206.027359 109.550034 204.491913 109.550034 202.700562 L 109.550034 89.077408 C 109.550034 87.541962 109.805939 86.262421 110.573662 85.238785 C 111.341385 83.959244 112.620926 82.935608 114.412285 82.679703 C 116.203636 82.423798 118.2509 82.167892 120.554077 82.167892 L 133.605377 82.167892 C 135.652649 82.167892 137.444 82.167892 138.979446 82.423798 C 140.514893 82.679703 141.794449 83.703339 142.562164 84.98288 C 143.073975 85.75061 143.329895 87.030136 143.5858 88.565598 C 143.5858 90.101028 143.5858 91.63649 143.841705 92.916031 C 144.09761 94.451477 144.353516 95.731018 144.865341 97.010559 C 145.121246 98.2901 145.888962 98.80191 147.168503 98.80191 C 147.424423 98.546005 147.936234 98.2901 148.192139 98.2901 C 148.448044 98.2901 148.959869 98.034195 149.215775 97.778275 C 150.23941 97.010559 151.263031 95.986923 152.030762 94.707382 C 152.798492 93.683762 153.566208 92.660126 154.845749 91.892395 C 155.613464 91.380585 156.12529 90.868759 156.6371 90.101028 C 157.148926 89.589233 157.660736 89.077408 158.428467 88.565598 C 159.963898 87.541962 161.499359 86.518326 163.29071 85.49469 C 164.826157 84.471054 166.361603 83.447433 168.152969 82.679703 C 169.944321 81.911972 171.735672 81.400162 173.527023 80.888351 C 175.31839 80.376541 177.109741 79.864731 178.901093 79.352905 C 179.412918 79.097 180.436554 79.097 181.972 79.097 C 183.251541 79.352905 184.275162 79.097 184.531082 78.841095 Z"/>
|
|
||||||
</g>
|
|
||||||
<g id="g3">
|
|
||||||
<path id="path2" fill="#894262" fill-rule="evenodd" stroke="none" d="M 194.653778 204.45752 C 194.653778 209.84726 190.284576 214.216522 184.894806 214.216522 C 179.505035 214.216522 175.135834 209.84726 175.135834 204.45752 C 175.135834 199.06778 179.505035 194.698517 184.894806 194.698517 C 190.284576 194.698517 194.653778 199.06778 194.653778 204.45752 Z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.7 KiB |
211
src/com/Base.js
211
src/com/Base.js
|
@ -1,211 +0,0 @@
|
||||||
import FipamoAdminAPI from '../libraries/FipamoAdminAPI';
|
|
||||||
import Maintenance from './controllers/MaintenanceManager';
|
|
||||||
import DataUitls from './utils/DataUtils';
|
|
||||||
import * as DataEvent from './events/DataEvent';
|
|
||||||
import DashManager from './controllers/DashManager';
|
|
||||||
import Notfications from './ui/Notifications';
|
|
||||||
const data = new DataUitls();
|
|
||||||
const notify = new Notfications();
|
|
||||||
|
|
||||||
export default class Base {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {
|
|
||||||
this.processing = false;
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
|
|
||||||
//TODO: Move init functions and set up to their own class
|
|
||||||
start() {
|
|
||||||
if (
|
|
||||||
document.getElementById('login') ||
|
|
||||||
document.querySelector('[role="site-restore"]')
|
|
||||||
) {
|
|
||||||
var options = document.getElementsByClassName('init-option');
|
|
||||||
for (let index = 0; index < options.length; index++) {
|
|
||||||
options[index].addEventListener('click', e => this.handleOptions(e));
|
|
||||||
}
|
|
||||||
if (document.getElementById('login')) {
|
|
||||||
document
|
|
||||||
.getElementById('login-btn')
|
|
||||||
.addEventListener('click', e => this.handleLogin(e));
|
|
||||||
} else {
|
|
||||||
document
|
|
||||||
.getElementById('init-blog')
|
|
||||||
.addEventListener('click', e => this.handleSetup(e));
|
|
||||||
document
|
|
||||||
.getElementById('blog-restore')
|
|
||||||
.addEventListener('click', e => this.handleRestore(e));
|
|
||||||
}
|
|
||||||
} else if (document.getElementById('dash-reset')) {
|
|
||||||
document
|
|
||||||
.getElementById('get-secret-btn')
|
|
||||||
.addEventListener('click', e => this.handleReset(e));
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementById('reset-btn')
|
|
||||||
.addEventListener('click', e => this.handleReset(e));
|
|
||||||
} else {
|
|
||||||
new DashManager();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
handleLogin(e) {
|
|
||||||
if (this.processing) return;
|
|
||||||
let self = this;
|
|
||||||
e.preventDefault();
|
|
||||||
let authForm = data.formDataToJSON(document.getElementById('login'));
|
|
||||||
//notify.alert('Looking, hold up', null);
|
|
||||||
let api = new FipamoAdminAPI();
|
|
||||||
this.processing = true;
|
|
||||||
api.login(authForm)
|
|
||||||
.then(response => {
|
|
||||||
self.processing = false;
|
|
||||||
if (response.type === DataEvent.REQUEST_LAME) {
|
|
||||||
e.target.innerHTML = response.message;
|
|
||||||
} else {
|
|
||||||
e.target.innerHTML = response.message;
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location = '/dashboard';
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
self.processing = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSetup(e) {
|
|
||||||
if (this.processing) return;
|
|
||||||
let self = this;
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
let setUpForm = data.formDataToJSON(document.getElementById('init-form'));
|
|
||||||
let mm = new Maintenance();
|
|
||||||
this.processing = true;
|
|
||||||
mm.create(setUpForm)
|
|
||||||
.then(response => {
|
|
||||||
if (response.type === DataEvent.API_INIT_LAME) {
|
|
||||||
self.processing = false;
|
|
||||||
e.target.innerHTML = response.message;
|
|
||||||
} else {
|
|
||||||
self.processing = false;
|
|
||||||
e.target.innerHTML = response.message;
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location = '/dashboard';
|
|
||||||
}, 700);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
self.processing = false;
|
|
||||||
//notify.alert(err, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleRestore(e) {
|
|
||||||
if (this.processing) return;
|
|
||||||
let self = this;
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
let mm = new Maintenance();
|
|
||||||
var form = document.getElementById('init-restore');
|
|
||||||
this.processing = true;
|
|
||||||
mm.restore(form)
|
|
||||||
.then(response => {
|
|
||||||
if (response.type === DataEvent.REQUEST_LAME) {
|
|
||||||
self.processing = false;
|
|
||||||
e.target.innerHTML = response.message;
|
|
||||||
} else {
|
|
||||||
self.processing = false;
|
|
||||||
e.target.innerHTML = response.message;
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location = '/dashboard';
|
|
||||||
}, 1500);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
self.processing = false;
|
|
||||||
e.target.innerHTML = err;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleReset(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
let self = this;
|
|
||||||
let mm = new Maintenance();
|
|
||||||
if (e.target.id == 'get-secret-btn') {
|
|
||||||
let data = {
|
|
||||||
email: document.getElementById('email').value,
|
|
||||||
task: 'retrieveSecret'
|
|
||||||
};
|
|
||||||
this.processing = true;
|
|
||||||
mm.secret(data)
|
|
||||||
.then(response => {
|
|
||||||
self.processing = false;
|
|
||||||
if (response.secret) {
|
|
||||||
document.getElementById('secret').value = response.secret;
|
|
||||||
notify.alert(response.message, true);
|
|
||||||
} else {
|
|
||||||
if (response.type == 'mailSent') {
|
|
||||||
notify.alert(response.message, true);
|
|
||||||
} else {
|
|
||||||
notify.alert(response.message, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
self.processing = false;
|
|
||||||
notify.alert(err, false);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
let data = {
|
|
||||||
newPass: document.getElementById('new_password').value,
|
|
||||||
newPassConfirm: document.getElementById('new_password2').value,
|
|
||||||
secret: document.getElementById('secret').value
|
|
||||||
};
|
|
||||||
mm.newPass(data)
|
|
||||||
.then(response => {
|
|
||||||
self.processing = false;
|
|
||||||
if (response.type == 'passNotCreated') {
|
|
||||||
notify.alert(response.message, false);
|
|
||||||
} else {
|
|
||||||
notify.alert(response.message, true);
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location = '/dashboard';
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
self.processing = false;
|
|
||||||
notify.alert(err, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handleOptions(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
let init = document.querySelector('[role="restore-fresh"]');
|
|
||||||
let restore = document.querySelector('[role="restore-backup"]');
|
|
||||||
if (e.target.id === 'init-switch-restore') {
|
|
||||||
init.style.display = 'none';
|
|
||||||
init.style.visibility = 'hidden';
|
|
||||||
|
|
||||||
restore.style.display = 'grid';
|
|
||||||
restore.style.visibility = 'visible';
|
|
||||||
} else {
|
|
||||||
init.style.display = 'grid';
|
|
||||||
init.style.visibility = 'visible';
|
|
||||||
|
|
||||||
restore.style.display = 'none';
|
|
||||||
restore.style.visibility = 'hidden';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
import Base from './Base';
|
|
||||||
|
|
||||||
document.addEventListener(
|
|
||||||
'DOMContentLoaded',
|
|
||||||
function () {
|
|
||||||
new Base();
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
|
@ -1,44 +0,0 @@
|
||||||
import FipamoAdminAPI from "../../libraries/FipamoAdminAPI";
|
|
||||||
import Notficaton from "../ui/Notifications";
|
|
||||||
const notify = new Notficaton();
|
|
||||||
export default class Mailer {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
sendMail() {
|
|
||||||
let mailData = {
|
|
||||||
content: "This is a test email"
|
|
||||||
};
|
|
||||||
let admin = new FipamoAdminAPI();
|
|
||||||
admin
|
|
||||||
.sendMail(mailData)
|
|
||||||
.then((result) => {
|
|
||||||
notify.alert(result.message, true);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
notify.alert(err.message, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
testMail() {
|
|
||||||
let mailData = {
|
|
||||||
content: "This is a test email",
|
|
||||||
mail_task: "TESTING"
|
|
||||||
};
|
|
||||||
let admin = new FipamoAdminAPI();
|
|
||||||
admin
|
|
||||||
.sendMail(mailData)
|
|
||||||
.then((result) => {
|
|
||||||
notify.alert(result.message, true);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
notify.alert(err.message, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
export default class NavActions {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
syncMenu() {
|
|
||||||
let navData = [];
|
|
||||||
let items = document.getElementById('nav-items').children;
|
|
||||||
for (let index = 0; index < items.length; index++) {
|
|
||||||
navData.push({
|
|
||||||
title: items[index].getElementsByTagName('label')[0].innerHTML,
|
|
||||||
id: items[index].id,
|
|
||||||
slug: items[index].getAttribute('data-slug'),
|
|
||||||
uuid: items[index].getAttribute('data-uuid'),
|
|
||||||
path: items[index].getAttribute('data-path')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = { menu: navData, remove: null };
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
resolve(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
removeItem(id) {
|
|
||||||
document.getElementById('nav-items').removeChild(document.getElementById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
import StringUtils from '../utils/StringUtils';
|
|
||||||
export default class PostActions {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
collectInfo(files) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let pageInfo = [];
|
|
||||||
let pageRef = document.querySelector('[role="file-manager"]');
|
|
||||||
//process html content for storage
|
|
||||||
let txt = document.createElement('textarea');
|
|
||||||
txt.innerHTML = document.getElementById('highlight-content').innerHTML;
|
|
||||||
let html = txt.value;
|
|
||||||
html = html.replace(/<\/?span[^>]*>/g, ''); //removes prism styling
|
|
||||||
html = html.replace(/<\/?br[^>]*>/g, '\n'); //convert back to encoded line break for storage
|
|
||||||
//build data object
|
|
||||||
pageInfo = {
|
|
||||||
id: pageRef.getAttribute('data-index'),
|
|
||||||
uuid: pageRef.getAttribute('data-uuid'),
|
|
||||||
layout: document.getElementById('page-templates').value,
|
|
||||||
current_title: pageRef.getAttribute('data-slug'),
|
|
||||||
content: html,
|
|
||||||
title: document.getElementById('post-title-text').value,
|
|
||||||
created: document.getElementById('post-date').getAttribute('data-raw'),
|
|
||||||
slug: new StringUtils().cleanString(
|
|
||||||
document.getElementById('post-title-text').value
|
|
||||||
),
|
|
||||||
tags: document.getElementById('post-tags').value,
|
|
||||||
menu: document
|
|
||||||
.getElementById('option-menu-pin')
|
|
||||||
.getAttribute('data-active'),
|
|
||||||
featured: document
|
|
||||||
.getElementById('option-feature')
|
|
||||||
.getAttribute('data-active'),
|
|
||||||
published: document
|
|
||||||
.getElementById('option-published')
|
|
||||||
.getAttribute('data-active'),
|
|
||||||
form_token: document.getElementById('form_token').value,
|
|
||||||
imageList: files.images,
|
|
||||||
fileList: files.files
|
|
||||||
};
|
|
||||||
|
|
||||||
resolve(pageInfo);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
export default class SettingsActions {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
getInfo() {
|
|
||||||
let handle = document.getElementById('settings-handle').value;
|
|
||||||
let email = document.getElementById('settings-email').value;
|
|
||||||
let url = document.getElementById('settings-url').value;
|
|
||||||
let title = document.getElementById('settings-title').value;
|
|
||||||
let desc = document.getElementById('settings-desc').value;
|
|
||||||
//let privacy = document.getElementById('privacy-toggle').getAttribute('data-private');
|
|
||||||
let render = document.getElementById('render-toggle').getAttribute('data-render');
|
|
||||||
let background = document
|
|
||||||
.querySelector('[role="background"]')
|
|
||||||
.style.backgroundImage.slice(4, -1)
|
|
||||||
.replace(/"/g, '');
|
|
||||||
let selected = '';
|
|
||||||
let selects = document.querySelectorAll('.theme-select');
|
|
||||||
let smtpDomain = document.getElementById('smtp-domain').value;
|
|
||||||
let smtpEmail = document.getElementById('smtp-email').value;
|
|
||||||
let smtpPass = document.getElementById('smtp-pass').value;
|
|
||||||
let mgDomain = document.getElementById('mg-domain').value;
|
|
||||||
let mgKey = document.getElementById('mg-key').value;
|
|
||||||
let mailActive = '';
|
|
||||||
let mailOptions = document.querySelectorAll('.mail-option');
|
|
||||||
let apiStatus = document
|
|
||||||
.getElementById('api-access-toggle')
|
|
||||||
.getAttribute('data-enabled');
|
|
||||||
let dynamicRenderStatus = document
|
|
||||||
.getElementById('dynamic-render-toggle')
|
|
||||||
.getAttribute('data-enabled');
|
|
||||||
var i, count;
|
|
||||||
for (i = 0, count = selects.length; i < count; i++) {
|
|
||||||
if (selects[i].getAttribute('data-enabled') == 'true')
|
|
||||||
selected = selects[i].id;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0, count = mailOptions.length; i < count; i++) {
|
|
||||||
if (mailOptions[i].getAttribute('data-enabled') == 'true')
|
|
||||||
mailActive = mailOptions[i].id;
|
|
||||||
}
|
|
||||||
let settingsData = {
|
|
||||||
global: {
|
|
||||||
base_url: url,
|
|
||||||
title: title,
|
|
||||||
descriptions: desc,
|
|
||||||
background: background,
|
|
||||||
private: false,
|
|
||||||
renderOnSave: render,
|
|
||||||
theme: selected,
|
|
||||||
externalAPI: apiStatus,
|
|
||||||
dynamicRender: dynamicRenderStatus
|
|
||||||
},
|
|
||||||
member: { handle: handle, email: email },
|
|
||||||
email: {
|
|
||||||
active: mailActive,
|
|
||||||
smtp: {
|
|
||||||
domain: smtpDomain,
|
|
||||||
email: smtpEmail,
|
|
||||||
password: smtpPass
|
|
||||||
},
|
|
||||||
mailgun: {
|
|
||||||
domain: mgDomain,
|
|
||||||
key: mgKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
resolve(settingsData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
import PostIndex from './PostIndex';
|
|
||||||
import SettingsIndex from './SettingsIndex';
|
|
||||||
import NaviIndex from './NavIndex';
|
|
||||||
import Menu from '../ui/Menu';
|
|
||||||
|
|
||||||
export default class DashManager {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {
|
|
||||||
this.currentDisplay = '';
|
|
||||||
this.urlPieces = document.URL.split('/');
|
|
||||||
this.chooseDisplay(this.urlPieces[4], this.urlPieces[5]);
|
|
||||||
//start main menu handler
|
|
||||||
new Menu();
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
start() {}
|
|
||||||
|
|
||||||
chooseDisplay(section, page) {
|
|
||||||
this.currentDisplay = '';
|
|
||||||
switch (section) {
|
|
||||||
case 'page':
|
|
||||||
this.currentDisplay = new PostIndex(page);
|
|
||||||
break;
|
|
||||||
case 'settings':
|
|
||||||
this.currentDisplay = new SettingsIndex();
|
|
||||||
break;
|
|
||||||
case 'navigation':
|
|
||||||
this.currentDisplay = new NaviIndex();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
//just chill
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
|
@ -1,292 +0,0 @@
|
||||||
//** REQUEST TYPES **//
|
|
||||||
export const REQUEST_TYPE_POST = 'POST';
|
|
||||||
export const REQUEST_TYPE_GET = 'GET';
|
|
||||||
export const REQUEST_TYPE_PUT = 'PUT';
|
|
||||||
export const REQUEST_TYPE_DELETE = 'DELETE';
|
|
||||||
//** POST CONTENT TYPES **//
|
|
||||||
export const CONTENT_TYPE_JSON = 'json';
|
|
||||||
export const CONTENT_TYPE_FORM = 'x-www-form-urlencoded';
|
|
||||||
//** API URLS **//
|
|
||||||
export const API_STATUS = '/api/v1/status';
|
|
||||||
export const API_INIT = '/api/v1/init';
|
|
||||||
export const API_RESTORE = '/api/v1/restore';
|
|
||||||
export const API_GET_SECRET = '/api/v1/get-secret';
|
|
||||||
export const API_RESET_PASS = '/api/v1/reset-password';
|
|
||||||
export const API_CREATE_BACKUP = '/api/v1/backup';
|
|
||||||
export const API_DOWNLOAD_BACKUP = '/api/v1/backup/download';
|
|
||||||
export const API_RESTORE_BACKUP = '/api/v1/backup/restore';
|
|
||||||
export const API_UPLOAD_AVATAR = '/api/v1/settings/add-avatar';
|
|
||||||
export const API_UPLOAD_BACKGROUND = '/api/v1/settings/add-feature-background';
|
|
||||||
export const API_IMAGE_UPLOAD = '/api/v1/page/add-entry-image';
|
|
||||||
export const API_FILES_UPLOAD = '/api/v1/files';
|
|
||||||
//** API TASKS **//
|
|
||||||
export const TASK_SITE_INIT = 'blogInit';
|
|
||||||
export const TASK_BACKUP_RESTORE = 'restoreBackup';
|
|
||||||
export const TASK_BACKUP_CREATE = 'createBackup';
|
|
||||||
export const TASK_GET_SECRET = 'retrieveSecret';
|
|
||||||
export const TASK_RESET_PASS = 'resetPassword';
|
|
||||||
export const TASK_UPLOAD_FILES = 'uploadFiles';
|
|
||||||
//** API STATUS **//
|
|
||||||
export const API_ACCESS_GOOD = 'apiUseAuthorized';
|
|
||||||
export const API_ACCESS_BAD = 'apiUseNotAuthorized';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A tub of methods for creating/restoring installs, resetting passwords and uploading images.
|
|
||||||
*/
|
|
||||||
class MaintenanceManager {
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {string} baseURL - url of site; uses local when empty
|
|
||||||
* @param {string} key - user api key
|
|
||||||
*/
|
|
||||||
constructor(baseURL = null, key = null) {
|
|
||||||
this.accetableFiles = [
|
|
||||||
'image/jpeg',
|
|
||||||
'image/gif',
|
|
||||||
'image/png',
|
|
||||||
'image/svg',
|
|
||||||
'audio/mpeg',
|
|
||||||
'video/mp4',
|
|
||||||
'application/pdf',
|
|
||||||
'text/plain',
|
|
||||||
'text/rtf'
|
|
||||||
];
|
|
||||||
this.percentComplete = 0; //for later
|
|
||||||
this.token = null;
|
|
||||||
this.baseURL = null;
|
|
||||||
this.key = null;
|
|
||||||
if (key) this.key = key;
|
|
||||||
if (baseURL) this.baseURL = baseURL;
|
|
||||||
//if key is valid, checks to see if a session is active and returns
|
|
||||||
this._request(
|
|
||||||
this.baseURL
|
|
||||||
? this.baseURL + API_STATUS + '?key=' + this.key
|
|
||||||
: API_STATUS + '?key=' + this.key
|
|
||||||
).then(response => {
|
|
||||||
if (response.type === API_ACCESS_GOOD) {
|
|
||||||
this.token = response.token;
|
|
||||||
} else {
|
|
||||||
//don't set token
|
|
||||||
//console.log("NO TOKEN");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Promise method used create new site from scratch. For local use only.
|
|
||||||
* @param {object} data - json object that contains data for set up
|
|
||||||
* @property {string} new_member_handle - handle for new user
|
|
||||||
* @property {string} new_member_email - email for new user
|
|
||||||
* @property {string} new_member_pass - password for new user
|
|
||||||
* @property {string} new_member_title - title for new user
|
|
||||||
*/
|
|
||||||
create(data) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this._request(
|
|
||||||
API_INIT,
|
|
||||||
null,
|
|
||||||
TASK_SITE_INIT,
|
|
||||||
REQUEST_TYPE_POST,
|
|
||||||
CONTENT_TYPE_JSON,
|
|
||||||
data
|
|
||||||
)
|
|
||||||
.then(result => {
|
|
||||||
resolve(result);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Promise method for restoring site from a previous back up. For local use only.
|
|
||||||
* @param {object} form - form object that contains restore data and files
|
|
||||||
* @property {string} restore_member_handle - handle for site user
|
|
||||||
* @property {string} restore_member_pass - password for site user
|
|
||||||
* @property {file} backup-upload - backup zip file
|
|
||||||
*/
|
|
||||||
restore(form) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
var url, event, method, type, data;
|
|
||||||
|
|
||||||
url = API_RESTORE;
|
|
||||||
event = TASK_BACKUP_RESTORE;
|
|
||||||
method = REQUEST_TYPE_POST;
|
|
||||||
type = CONTENT_TYPE_FORM;
|
|
||||||
data = new FormData(form);
|
|
||||||
this._request(url, null, event, method, type, data)
|
|
||||||
.then(result => {
|
|
||||||
resolve(result);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Promise method for creating a zip back up of current site. For local use only.
|
|
||||||
*/
|
|
||||||
|
|
||||||
backup() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
var url, event, method, type, data;
|
|
||||||
|
|
||||||
url = API_CREATE_BACKUP;
|
|
||||||
event = TASK_BACKUP_CREATE;
|
|
||||||
method = REQUEST_TYPE_POST;
|
|
||||||
type = CONTENT_TYPE_JSON;
|
|
||||||
data = { task: 'create_backup' };
|
|
||||||
this._request(url, null, event, method, type, data)
|
|
||||||
.then(result => {
|
|
||||||
resolve(result);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Promise method for retrieving user secret key. For local use only.
|
|
||||||
* @param {object} data - json object that contains data for set up
|
|
||||||
* @property {string} email - email for site user
|
|
||||||
*/
|
|
||||||
|
|
||||||
secret(data) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this._request(
|
|
||||||
API_GET_SECRET,
|
|
||||||
TASK_GET_SECRET,
|
|
||||||
REQUEST_TYPE_POST,
|
|
||||||
CONTENT_TYPE_JSON,
|
|
||||||
data
|
|
||||||
)
|
|
||||||
.then(result => {
|
|
||||||
resolve(result);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Promise method for resetting password for user. For local use only.
|
|
||||||
* @param {object} data - json object that contains data for set up
|
|
||||||
* @property {string} new_password - password for user
|
|
||||||
* @property {string} new_password2 - confirm password for user
|
|
||||||
* @property {string} secret - secret key for user
|
|
||||||
*/
|
|
||||||
|
|
||||||
newPass(data) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this._request(
|
|
||||||
API_RESET_PASS,
|
|
||||||
TASK_RESET_PASS,
|
|
||||||
REQUEST_TYPE_POST,
|
|
||||||
CONTENT_TYPE_JSON,
|
|
||||||
data
|
|
||||||
)
|
|
||||||
.then(result => {
|
|
||||||
resolve(result);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Promise method for uploading files [todo: change to uploading files]
|
|
||||||
* @param {string} type - type of upload
|
|
||||||
* @param {input} files - form input containing files
|
|
||||||
*/
|
|
||||||
filesUpload(type, files, progress = null) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let url = API_FILES_UPLOAD;
|
|
||||||
|
|
||||||
if (this.baseURL) {
|
|
||||||
files.append('key', this.key);
|
|
||||||
files.append('remote', true);
|
|
||||||
} else {
|
|
||||||
files.append('remote', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._request(
|
|
||||||
url,
|
|
||||||
progress,
|
|
||||||
TASK_UPLOAD_FILES,
|
|
||||||
REQUEST_TYPE_POST,
|
|
||||||
CONTENT_TYPE_FORM,
|
|
||||||
files
|
|
||||||
)
|
|
||||||
.then(r => {
|
|
||||||
resolve(r);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------
|
|
||||||
// private
|
|
||||||
//--------------------------
|
|
||||||
_request(
|
|
||||||
requestURL,
|
|
||||||
progressBar = null,
|
|
||||||
eventType,
|
|
||||||
requestType = REQUEST_TYPE_GET,
|
|
||||||
contentType = CONTENT_TYPE_JSON,
|
|
||||||
requestData = null
|
|
||||||
) {
|
|
||||||
var self = this;
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
var request = new XMLHttpRequest();
|
|
||||||
|
|
||||||
request.upload.addEventListener('progress', e =>
|
|
||||||
self.handleLoadProgress(e, progressBar)
|
|
||||||
);
|
|
||||||
request.open(requestType, requestURL, true);
|
|
||||||
request.onload = () => {
|
|
||||||
if (request.status == 200) {
|
|
||||||
let response = JSON.parse(request['response']);
|
|
||||||
resolve(response);
|
|
||||||
} else {
|
|
||||||
let error = JSON.parse(request['response']);
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (requestType == REQUEST_TYPE_PUT || requestType == REQUEST_TYPE_POST) {
|
|
||||||
if (eventType === TASK_UPLOAD_FILES)
|
|
||||||
request.setRequestHeader('fipamo-access-token', self.token);
|
|
||||||
switch (contentType) {
|
|
||||||
case CONTENT_TYPE_JSON:
|
|
||||||
request.setRequestHeader(
|
|
||||||
'Content-type',
|
|
||||||
'application/' + contentType
|
|
||||||
);
|
|
||||||
request.send(JSON.stringify(requestData));
|
|
||||||
break;
|
|
||||||
case CONTENT_TYPE_FORM:
|
|
||||||
request.send(requestData);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
request.send();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
handleLoadProgress(e, progressBar) {
|
|
||||||
let percent = Math.ceil((e.loaded / e.total) * 100);
|
|
||||||
//if a progress bar element is present, talk to it
|
|
||||||
if (progressBar != null) {
|
|
||||||
progressBar.style.width = percent + '%';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { MaintenanceManager as default };
|
|
|
@ -1,74 +0,0 @@
|
||||||
import FipamoAdminAPI, { TASK_SYNC_NAV } from '../../libraries/FipamoAdminAPI';
|
|
||||||
import NavActions from '../actions/NavActions';
|
|
||||||
import * as DataEvent from '../events/DataEvent';
|
|
||||||
import Notifications from '../ui/Notifications';
|
|
||||||
import Sortable from 'sortablejs';
|
|
||||||
const notify = new Notifications();
|
|
||||||
|
|
||||||
export default class NavIndex {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {
|
|
||||||
this.processing = false;
|
|
||||||
this.admin = new FipamoAdminAPI(null);
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
start() {
|
|
||||||
//grabs elements and makes them sortables
|
|
||||||
let self = this;
|
|
||||||
Sortable.create(document.getElementById('nav-items'), {
|
|
||||||
onUpdate: () => {
|
|
||||||
new NavActions().syncMenu().then(data => {
|
|
||||||
notify.alert('Updating Menu', null);
|
|
||||||
self.admin.sync(TASK_SYNC_NAV, data).then(r => {
|
|
||||||
if (r.type == DataEvent.MENU_UPDATED) {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
} else {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var nav = document.querySelectorAll('.nav-btn');
|
|
||||||
for (var i = 0, length = nav.length; i < length; i++) {
|
|
||||||
nav[i].addEventListener('click', e => this.handleNavButton(e), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
handleNavButton(e) {
|
|
||||||
if (this.processing) return;
|
|
||||||
let id = '';
|
|
||||||
let self = this;
|
|
||||||
switch (e.target.id) {
|
|
||||||
case 'remove-item':
|
|
||||||
id = e.target.getAttribute('data-id');
|
|
||||||
new NavActions().removeItem(id);
|
|
||||||
new NavActions().syncMenu().then(data => {
|
|
||||||
data.remove = e.target.getAttribute('data-uuid');
|
|
||||||
notify.alert('Editing Menu', null);
|
|
||||||
self.processing = true;
|
|
||||||
self.admin.sync(TASK_SYNC_NAV, data).then(r => {
|
|
||||||
self.processing = false;
|
|
||||||
if (r.type == DataEvent.MENU_UPDATED) {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
} else {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'edit-item':
|
|
||||||
self.processing = false;
|
|
||||||
window.location =
|
|
||||||
'/dashboard/page/edit/' + e.target.getAttribute('data-id');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,228 +0,0 @@
|
||||||
//TOOLS
|
|
||||||
import FipamoAdminAPI, {
|
|
||||||
TASK_PAGE_CREATE,
|
|
||||||
TASK_PAGE_EDIT,
|
|
||||||
TASK_PAGE_DELETE
|
|
||||||
} from '../../libraries/FipamoAdminAPI';
|
|
||||||
import Maintenance from './MaintenanceManager';
|
|
||||||
import * as DataEvent from '../events/DataEvent';
|
|
||||||
import PageActions from '../actions/PageActions';
|
|
||||||
import * as EditorEvent from '../events/EditorEvent';
|
|
||||||
//import TinyDatePicker from 'tiny-date-picker'; TODO: Reactivate for scheduled publishing
|
|
||||||
import TextEditor from '../ui/TextEditor';
|
|
||||||
import Notfications from '../ui/Notifications';
|
|
||||||
import FileManager from '../ui/FileManager';
|
|
||||||
const notify = new Notfications();
|
|
||||||
export default class PostEditor {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {
|
|
||||||
this.processing = false;
|
|
||||||
let self = 'this';
|
|
||||||
this.admin = new FipamoAdminAPI(null, document.getElementById('notify-progress'));
|
|
||||||
this.mm = 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('[role="file-manager"]').getAttribute('data-index')) {
|
|
||||||
this.postID = document
|
|
||||||
.querySelector('[role="file-manager"]')
|
|
||||||
.getAttribute('data-index');
|
|
||||||
this.postUUID = document
|
|
||||||
.querySelector('[role="file-manager"]')
|
|
||||||
.getAttribute('data-uuid');
|
|
||||||
this.postLayout = document
|
|
||||||
.querySelector('[role="file-manager"]')
|
|
||||||
.getAttribute('data-layout');
|
|
||||||
}
|
|
||||||
if (document.getElementById('edit')) {
|
|
||||||
this.editor = new TextEditor(
|
|
||||||
document.getElementById('edit'),
|
|
||||||
document.querySelector('[role="file-manager"]').offsetHeight +
|
|
||||||
document.querySelector('[role="page-meta"]').offsetHeight +
|
|
||||||
document.querySelector('[role="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('[role="file-drop"]')) {
|
|
||||||
//insert fileManager here
|
|
||||||
this.fm = new FileManager(
|
|
||||||
document.querySelector('[role="file-drop"]'),
|
|
||||||
document.getElementById('page-files-upload'),
|
|
||||||
document.querySelector('[role="page-images-list"]'),
|
|
||||||
document.querySelector('[role="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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// 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.admin
|
|
||||||
.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.admin
|
|
||||||
.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.mm
|
|
||||||
.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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
import PageEditor from "./PageEditor";
|
|
||||||
export default class PostIndex {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor(page) {
|
|
||||||
this.currentPage = null;
|
|
||||||
this.choosePage(page);
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
start() {}
|
|
||||||
choosePage(page) {
|
|
||||||
this.currentPage = "";
|
|
||||||
switch (page) {
|
|
||||||
case "edit":
|
|
||||||
case "add":
|
|
||||||
this.currentPage = new PageEditor();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//just chill
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
|
@ -1,268 +0,0 @@
|
||||||
import SettingsActions from '../actions/SettingsActions';
|
|
||||||
import Maintenance from './MaintenanceManager';
|
|
||||||
import FipamoAdminAPI, { TASK_SYNC_SETTNIGS } from '../../libraries/FipamoAdminAPI';
|
|
||||||
import * as DataEvent from '../../../src/com/events/DataEvent';
|
|
||||||
import Mailer from '../actions/Mailer';
|
|
||||||
import Notifications from '../ui/Notifications';
|
|
||||||
const notify = new Notifications();
|
|
||||||
export default class SettingsIndex {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {
|
|
||||||
this.processing = false;
|
|
||||||
this.start();
|
|
||||||
this.admin = new FipamoAdminAPI(null);
|
|
||||||
this.mm = new Maintenance(null, null);
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
start() {
|
|
||||||
let self = this;
|
|
||||||
//handle save button
|
|
||||||
document.getElementById('save-toggle').addEventListener('click', () =>
|
|
||||||
new SettingsActions()
|
|
||||||
.getInfo()
|
|
||||||
.then(data => {
|
|
||||||
notify.alert('Saving Settings', null);
|
|
||||||
self.admin.sync(TASK_SYNC_SETTNIGS, data).then(r => {
|
|
||||||
if (r.type == DataEvent.SETTINGS_UPDATED) {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
} else {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
//console.log(err);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
//handle set up image uploads
|
|
||||||
document.querySelector('[role="avatar"]').addEventListener('click', () => {
|
|
||||||
document.getElementById('avatar-upload').click();
|
|
||||||
});
|
|
||||||
document.querySelector('[role="background"]').addEventListener('click', () => {
|
|
||||||
document.getElementById('background-upload').click();
|
|
||||||
});
|
|
||||||
document.getElementById('avatar-upload').addEventListener(
|
|
||||||
'change',
|
|
||||||
e => {
|
|
||||||
self.handleImageUpload(e.target.id, e.target.files);
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
document.getElementById('background-upload').addEventListener(
|
|
||||||
'change',
|
|
||||||
e => {
|
|
||||||
self.handleImageUpload(e.target.id, e.target.files);
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
//handle api access toggle
|
|
||||||
var apiButton = document.getElementById('api-access-toggle');
|
|
||||||
var apiStatus = document.getElementById('api-status');
|
|
||||||
apiButton.addEventListener('click', e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
if (apiButton.getAttribute('data-enabled') == 'false') {
|
|
||||||
apiButton.setAttribute('data-enabled', 'true');
|
|
||||||
apiStatus.innerHTML = 'API ACCESS IS ENABLED';
|
|
||||||
} else {
|
|
||||||
apiButton.setAttribute('data-enabled', 'false');
|
|
||||||
apiStatus.innerHTML = 'API ACCESS IS DISABLED';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//handle dynamic page rendering
|
|
||||||
var dynamicRenderButton = document.getElementById('dynamic-render-toggle');
|
|
||||||
var dynamicRenderStatus = document.getElementById('dynamic-render-status');
|
|
||||||
dynamicRenderButton.addEventListener('click', e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
if (dynamicRenderButton.getAttribute('data-enabled') == 'false') {
|
|
||||||
dynamicRenderButton.setAttribute('data-enabled', 'true');
|
|
||||||
dynamicRenderStatus.innerHTML = 'DYNAMIC PAGE RENDERING';
|
|
||||||
} else {
|
|
||||||
dynamicRenderButton.setAttribute('data-enabled', 'false');
|
|
||||||
dynamicRenderStatus.innerHTML = 'STATIC PAGE RENDERING';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementById('send-mail')
|
|
||||||
.addEventListener('click', e => this.handleMailer(e));
|
|
||||||
document
|
|
||||||
.getElementById('publish-pages')
|
|
||||||
.addEventListener('click', e => this.handlePublished(e));
|
|
||||||
//handle page render on save toggle
|
|
||||||
document
|
|
||||||
.getElementById('render-toggle')
|
|
||||||
.addEventListener('click', e => this.toggleRender(e));
|
|
||||||
//handle theme toggle
|
|
||||||
let themeBtns = document.querySelectorAll('.theme-select');
|
|
||||||
for (var i = 0, length = themeBtns.length; i < length; i++) {
|
|
||||||
themeBtns[i].addEventListener('click', e => this.handleThemes(e));
|
|
||||||
}
|
|
||||||
//handle mail options
|
|
||||||
let mailBtn = document.querySelectorAll('.mail-option');
|
|
||||||
for (i = 0, length = mailBtn.length; i < length; i++) {
|
|
||||||
mailBtn[i].addEventListener('click', e => this.handleMailOptions(e));
|
|
||||||
}
|
|
||||||
//handle backup from settings [disabled]
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementById('create-backup')
|
|
||||||
.addEventListener('click', e => this.handleBackup(e));
|
|
||||||
|
|
||||||
/*
|
|
||||||
document
|
|
||||||
.getElementById("reindex-pages")
|
|
||||||
.addEventListener("click", (e) => this.handleReindex(e));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
togglePrivacy(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
if (e.target.getAttribute('data-private') == 'false') {
|
|
||||||
e.target.setAttribute('data-private', 'true');
|
|
||||||
e.target.innerHTML = 'SITE IS PUBLIC';
|
|
||||||
} else {
|
|
||||||
e.target.setAttribute('data-private', 'false');
|
|
||||||
e.target.innerHTML = 'SITE IS PRIVATE';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
toggleRender(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
let button = document.getElementById('render-toggle');
|
|
||||||
if (button.getAttribute('data-render') == 'false') {
|
|
||||||
button.setAttribute('data-render', 'true');
|
|
||||||
//e.target.innerHTML = 'RENDER PAGES ON SAVE';
|
|
||||||
} else {
|
|
||||||
button.setAttribute('data-render', 'false');
|
|
||||||
//e.target.innerHTML = "DON'T RENDER PAGES ON SAVE";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handleMailer() {
|
|
||||||
let mailer = new Mailer();
|
|
||||||
mailer.testMail();
|
|
||||||
//mailer.sendMail();
|
|
||||||
}
|
|
||||||
handleThemes(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
let themes = document.querySelectorAll('.theme-select');
|
|
||||||
for (var i = 0, length = themes.length; i < length; i++) {
|
|
||||||
e.target.id == themes[i].id
|
|
||||||
? themes[i].setAttribute('data-enabled', 'true')
|
|
||||||
: themes[i].setAttribute('data-enabled', 'false');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handleMailOptions(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
let smtp = document.getElementById('mail-smtp');
|
|
||||||
let mailgun = document.getElementById('mail-mg');
|
|
||||||
let mail = document.querySelectorAll('.mail-option');
|
|
||||||
for (var i = 0, length = mail.length; i < length; i++) {
|
|
||||||
if (e.target.id == mail[i].id) {
|
|
||||||
mail[i].setAttribute('data-enabled', 'true');
|
|
||||||
if (e.target.id == 'option-smtp') {
|
|
||||||
smtp.setAttribute('data-enabled', 'true');
|
|
||||||
mailgun.setAttribute('data-enabled', 'false');
|
|
||||||
} else if (e.target.id == 'option-none') {
|
|
||||||
smtp.setAttribute('data-enabled', 'false');
|
|
||||||
mailgun.setAttribute('data-enabled', 'false');
|
|
||||||
} else {
|
|
||||||
smtp.setAttribute('data-enabled', 'false');
|
|
||||||
mailgun.setAttribute('data-enabled', 'true');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mail[i].setAttribute('data-enabled', 'false');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handleImageUpload(type, files) {
|
|
||||||
notify.alert('Uploading Image... ', null);
|
|
||||||
let self = this;
|
|
||||||
notify.alert('Uploading Image', null);
|
|
||||||
let upload = new FormData();
|
|
||||||
upload.enctype = 'multipart/form-data';
|
|
||||||
upload.append('source', type);
|
|
||||||
upload.append('upload_files[]', files[0], files[0].name);
|
|
||||||
|
|
||||||
this.mm
|
|
||||||
.filesUpload(files[0].type, upload)
|
|
||||||
.then(r => {
|
|
||||||
if (type == 'avatar-upload') {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
document.querySelector('[role="avatar"]').style.background =
|
|
||||||
'url(' + r.filePath + ') no-repeat center center / cover';
|
|
||||||
} else {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
document.querySelector('[role="background"]').style.background =
|
|
||||||
'url(' + r.filePath + ') no-repeat center center / cover';
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
//console.log(err)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
handlePublished(e) {
|
|
||||||
if (this.processing) return;
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
let self = this;
|
|
||||||
let task = { task: 'PUBLISH_ALL' };
|
|
||||||
this.processing = true;
|
|
||||||
notify.alert('Publishing site...', null);
|
|
||||||
this.admin
|
|
||||||
.publish(task)
|
|
||||||
.then(r => {
|
|
||||||
self.processing = false;
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
self.processing = false;
|
|
||||||
notify.alert(err, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleBackup(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
notify.alert('Creating backup', null);
|
|
||||||
this.mm
|
|
||||||
.backup()
|
|
||||||
.then(r => {
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
notify.alert(err, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleReindex(e) {
|
|
||||||
if (this.processing) return;
|
|
||||||
let self = this;
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
let task = { task: 'cleanup pages indexes' };
|
|
||||||
this.processing = true;
|
|
||||||
notify.alert('Cleaning up page indexes', null);
|
|
||||||
this.admin
|
|
||||||
.handleReindex(task)
|
|
||||||
.then(r => {
|
|
||||||
self.processing = false;
|
|
||||||
notify.alert(r.message, true);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
self.processing = false;
|
|
||||||
notify.alert(err, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
export const MEMBER_STATUS = 'memberStatus';
|
|
||||||
export const LOGIN_STATUS = 'loginStatus';
|
|
||||||
export const SUPPORTER_FOUND = 'SUPPORTER FOUND';
|
|
||||||
export const SUPPORTER_LISTED = 'SUPPORTER LISTED';
|
|
||||||
export const SUPPORTER_NOT_FOUND = 'SUPPORTER NOT FOUND';
|
|
||||||
export const MEMBER_ADDED = 'MEMBER ADDED';
|
|
||||||
export const MEMBER_NOT_ADDED = 'MEMBER NOT ADDED';
|
|
||||||
export const MEMBER_LOGIN_GOOD = 'MEMBER LOGIN GOOD';
|
|
||||||
export const MEMBER_LOGIN_LAME = 'MEMBER LOGIN LAME';
|
|
||||||
export const MEMBER_EXISTS = 'USER ALREADY EXISTS';
|
|
||||||
export const MEMBER_LOGIN_MISSING = 'Missing credentials';
|
|
||||||
|
|
||||||
class AuthEvent {
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
||||||
export default new AuthEvent();
|
|
|
@ -1,51 +0,0 @@
|
||||||
export const AUTH_STATUS = "getAuthStatus";
|
|
||||||
export const REQUEST_GOOD = "requestGood";
|
|
||||||
export const REQUEST_LAME = "requestLame";
|
|
||||||
export const API_REQUEST_GOOD = "apiUseAuthorized";
|
|
||||||
export const API_REQUEST_LAME = "apiUseNotAuthorized";
|
|
||||||
export const IMG_REQUEST_GOOD = "imgRequestGood";
|
|
||||||
export const IMG_REQUEST_LAME = "imgRequestLame";
|
|
||||||
export const SETTINGS_LOADED = "settingsLoaded";
|
|
||||||
export const POST_IMAGE_ADDED = "postImageAdded";
|
|
||||||
export const FEATURE_IMAGE_ADDED = "featureImageAdded";
|
|
||||||
export const PAGE_ERROR = "postError";
|
|
||||||
export const PAGE_ADDED = "postAdded";
|
|
||||||
export const PAGE_UPDATED = "postUpdated";
|
|
||||||
export const PAGE_DELETED = "postImageAdded";
|
|
||||||
export const PAGES_RENDERED = "pagesRendered";
|
|
||||||
export const PAGES_NOT_RENDERED = "pagesNotRendered";
|
|
||||||
export const TAG_PAGES_RENDERED = "tagPagesRendered";
|
|
||||||
export const TAG_PAGES_NOT_RENDERED = "tagPagesNotRendered";
|
|
||||||
export const SETTINGS_UPDATED = "settingsUpdated";
|
|
||||||
export const SETTINGS_NOT_UPDATED = "settingsNotUpdated";
|
|
||||||
export const MENU_ADD_ITEM = "menuAddItem";
|
|
||||||
export const MENU_DELETE_ITEM = "menuDeleteItem";
|
|
||||||
export const MENU_UPDATED = "menuUpdated";
|
|
||||||
export const AVATAR_UPLOADED = "avatarUploaded";
|
|
||||||
export const SITE_BACKGROUND_UPLOADED = "siteBackgroundUploaded";
|
|
||||||
export const UPLOAD_PROGRESS = "uploadProgress";
|
|
||||||
export const API_PAGE_WRITE = "writingItDown";
|
|
||||||
export const API_PAGE_CREATE = "writingNewEntry";
|
|
||||||
export const API_PAGE_DELETE = "erasingPage";
|
|
||||||
export const API_SETTINGS_WRITE = "savingSettings";
|
|
||||||
export const API_BACKUP_CREATE = "createBackup";
|
|
||||||
export const API_BACKUP_DOWNLOAD = "downloadBackup";
|
|
||||||
export const API_BACKUP_RESTORE = "downloadBackup";
|
|
||||||
export const API_IMAGES_UPLOAD = "uploadProfileImages";
|
|
||||||
export const API_RENDER_PAGES = "renderPages";
|
|
||||||
export const API_REINDEX_PAGES = "reindexPages";
|
|
||||||
export const API_INIT = "blogInit";
|
|
||||||
export const API_INIT_GOOD = "blogInitGood";
|
|
||||||
export const API_INIT_LAME = "blogInitLame";
|
|
||||||
export const API_GET_SECRET = "retrieveSecret";
|
|
||||||
export const API_RESET_PASS = "resetPassword";
|
|
||||||
export const SEND_MAIL = "sendMail";
|
|
||||||
class DataEvent {
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
||||||
export default new DataEvent();
|
|
|
@ -1,14 +0,0 @@
|
||||||
export const EDITOR_DELETE = 'editorDelete';
|
|
||||||
export const EDITOR_UPLOAD_POST_IMAGE = 'editorUploadImage';
|
|
||||||
export const EDITOR_SAVE = 'editorSave';
|
|
||||||
export const EDITOR_UPDATE = 'editorUpdate';
|
|
||||||
|
|
||||||
class EditorEvent {
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
||||||
export default new EditorEvent();
|
|
|
@ -1,52 +0,0 @@
|
||||||
class EventEmitter {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {
|
|
||||||
this.listeners = new Map();
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
addListener(label, callback) {
|
|
||||||
this.listeners.has(label) || this.listeners.set(label, []);
|
|
||||||
this.listeners.get(label).push(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeListener(label, callback) {
|
|
||||||
var isFunction = function(obj) {
|
|
||||||
return typeof obj == 'function' || false;
|
|
||||||
};
|
|
||||||
|
|
||||||
var listeners = this.listeners.get(label),
|
|
||||||
index;
|
|
||||||
|
|
||||||
if (listeners && listeners.length) {
|
|
||||||
index = listeners.reduce((i, listener, index) => {
|
|
||||||
return isFunction(listener) && listener === callback ? (i = index) : i;
|
|
||||||
}, -1);
|
|
||||||
|
|
||||||
if (index > -1) {
|
|
||||||
listeners.splice(index, 1);
|
|
||||||
this.listeners.set(label, listeners);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
emitEvent(label, ...args) {
|
|
||||||
var listeners = this.listeners.get(label);
|
|
||||||
if (listeners && listeners.length) {
|
|
||||||
listeners.forEach(listener => {
|
|
||||||
listener(...args);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
||||||
export default EventEmitter;
|
|
|
@ -1,296 +0,0 @@
|
||||||
import Sortable from 'sortablejs';
|
|
||||||
import anime from 'animejs/lib/anime.es.js';
|
|
||||||
import DataUtils from '../utils/DataUtils';
|
|
||||||
import Notfications from './Notifications.js';
|
|
||||||
import Maintenance from '../controllers/MaintenanceManager';
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
export default class Menu {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {
|
|
||||||
this.mobile = false;
|
|
||||||
this.mobileMenu = document.querySelector('[role="mobile-menu"]');
|
|
||||||
document
|
|
||||||
.querySelector('[role="menu-toggle"]')
|
|
||||||
.addEventListener('click', e => this.handleMobile(e));
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
start() {}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
handleMobile(e) {
|
|
||||||
if (this.mobile) {
|
|
||||||
this.mobile = false;
|
|
||||||
this.mobileMenu.style.display = 'none';
|
|
||||||
} else {
|
|
||||||
this.mobile = true;
|
|
||||||
this.mobileMenu.style.display = 'inline';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
import anime from 'animejs/lib/anime.es.js';
|
|
||||||
const notifcation = document.querySelector('[role="notify-message"]');
|
|
||||||
const notify = document.getElementById('notify-message');
|
|
||||||
const responseText = document.querySelector('[role="response-text"]');
|
|
||||||
const notifyText = document.querySelector('[role="notify-text"]');
|
|
||||||
const notifyIcons = document.querySelector('[role="notify-icons"]');
|
|
||||||
//const notifyProgress = document.getElementById('notify-progress');
|
|
||||||
const iconGood = document.querySelector('[role="notify-good"]');
|
|
||||||
const iconNotGood = document.querySelector('[role="notify-notgood"]');
|
|
||||||
const iconWorking = document.querySelector('[role="notify-working"]');
|
|
||||||
|
|
||||||
export default class Notfications {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
|
|
||||||
alert(text, status) {
|
|
||||||
iconWorking.style.display = 'none';
|
|
||||||
iconGood.style.display = 'none';
|
|
||||||
iconNotGood.style.display = 'none';
|
|
||||||
|
|
||||||
var color = '';
|
|
||||||
responseText.innerHTML = text;
|
|
||||||
if (status !== null) {
|
|
||||||
if (status) {
|
|
||||||
color = '#32cd32';
|
|
||||||
iconWorking.style.display = 'none';
|
|
||||||
iconGood.style.display = 'block';
|
|
||||||
} else {
|
|
||||||
color = '#F64747';
|
|
||||||
iconWorking.style.display = 'none';
|
|
||||||
iconNotGood.style.display = 'block';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
color = '#200317';
|
|
||||||
iconWorking.style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
new anime({
|
|
||||||
targets: document.querySelector('[role="top-nav"]'),
|
|
||||||
rotateX: '180deg',
|
|
||||||
easing: 'easeOutQuint'
|
|
||||||
});
|
|
||||||
|
|
||||||
new anime({
|
|
||||||
targets: document.querySelector('[role="notify"]'),
|
|
||||||
rotateX: '10deg',
|
|
||||||
easing: 'easeOutQuint',
|
|
||||||
complete: () => {
|
|
||||||
new anime({
|
|
||||||
targets: notifyIcons,
|
|
||||||
width: 39,
|
|
||||||
opacity: 1,
|
|
||||||
easing: 'easeInQuint',
|
|
||||||
duration: 300
|
|
||||||
});
|
|
||||||
|
|
||||||
new anime({
|
|
||||||
targets: notifyText,
|
|
||||||
backgroundColor: color,
|
|
||||||
opacity: 1,
|
|
||||||
easing: 'easeInOutQuad',
|
|
||||||
duration: 400,
|
|
||||||
complete: () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (status !== null) {
|
|
||||||
anime({
|
|
||||||
targets: notifyText,
|
|
||||||
backgroundColor: color,
|
|
||||||
opacity: 0,
|
|
||||||
easing: 'easeInOutQuad',
|
|
||||||
duration: 400
|
|
||||||
});
|
|
||||||
|
|
||||||
anime({
|
|
||||||
targets: notifyIcons,
|
|
||||||
width: 0,
|
|
||||||
opacity: 0,
|
|
||||||
easing: 'easeOutQuint',
|
|
||||||
duration: 350
|
|
||||||
});
|
|
||||||
|
|
||||||
new anime({
|
|
||||||
targets: document.querySelector('[role="top-nav"]'),
|
|
||||||
rotateX: '0deg',
|
|
||||||
easing: 'easeOutQuint'
|
|
||||||
});
|
|
||||||
|
|
||||||
new anime({
|
|
||||||
targets: document.querySelector('[role="notify"]'),
|
|
||||||
rotateX: '180deg',
|
|
||||||
easing: 'easeOutQuint'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 2500);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
|
@ -1,203 +0,0 @@
|
||||||
import * as DataEvent from '../events/DataEvent';
|
|
||||||
import EventEmitter from '../events/EventEmitter';
|
|
||||||
import * as EditorEvent from '../events/EditorEvent';
|
|
||||||
import Prism from 'prismjs';
|
|
||||||
class TextEditor extends EventEmitter {
|
|
||||||
/**
|
|
||||||
* Text Editor UI Component
|
|
||||||
* @constructor
|
|
||||||
* @param {object} textEditor - Text area that will edit text
|
|
||||||
* @param {number} scrollLimit - YPos where editor position will become fixed
|
|
||||||
*/
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor(textEditor, scrollLimit) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
document
|
|
||||||
.querySelector('[role="text-editor-control"]')
|
|
||||||
.addEventListener('scroll', e => {
|
|
||||||
console.log('HERE');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.addEventListener('scroll', e => {
|
|
||||||
var fixLimit = scrollLimit;
|
|
||||||
console.log('POSITION', document.body.scrollTop + ' : ' + fixLimit);
|
|
||||||
if (document.body.scrollTop + 5 >= fixLimit) {
|
|
||||||
document
|
|
||||||
.querySelector('[role="text-editor-control"]')
|
|
||||||
.classList.add('control-freeze');
|
|
||||||
} else {
|
|
||||||
document
|
|
||||||
.querySelector('[role="text-editor-control"]')
|
|
||||||
.classList.remove('control-freeze');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
document.getElementById('edit').addEventListener('input', e => {
|
|
||||||
let result_element = document.querySelector('#highlight-content');
|
|
||||||
this.textEditor = textEditor;
|
|
||||||
|
|
||||||
// Update code
|
|
||||||
let text = e.target.value;
|
|
||||||
result_element.innerHTML = text
|
|
||||||
.replace(new RegExp('&', 'g'), '&')
|
|
||||||
.replace(new RegExp('<', 'g'), '<');
|
|
||||||
let editorHeight = document.getElementById('highlight').offsetHeight;
|
|
||||||
document.querySelector('[role="edit-post-wrapper"]').style.height =
|
|
||||||
editorHeight + 'px';
|
|
||||||
e.target.style.height = editorHeight + 30 + 'px'; //TODO: yeah, it's ugly but it works for now, fix soon
|
|
||||||
// Syntax Highlight
|
|
||||||
Prism.highlightElement(result_element);
|
|
||||||
});
|
|
||||||
document.getElementById('edit').addEventListener('scroll', e => {
|
|
||||||
/* Scroll result to scroll coords of event - sync with textarea */
|
|
||||||
let result_element = document.querySelector('#highlight');
|
|
||||||
// Get and set x and y
|
|
||||||
result_element.scrollTop = e.scrollTop;
|
|
||||||
result_element.scrollLeft = e.scrollLeft;
|
|
||||||
});
|
|
||||||
document.getElementById('edit').dispatchEvent(new Event('input'));
|
|
||||||
this.setInputs();
|
|
||||||
|
|
||||||
//freeze editor formatting so it doesn't scroll off screen
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
setInputs() {
|
|
||||||
var editorButtons = document.querySelectorAll('.editor-button');
|
|
||||||
for (var i = 0, length = editorButtons.length; i < length; i++) {
|
|
||||||
editorButtons[i].addEventListener(
|
|
||||||
'click',
|
|
||||||
e => this.handleEditorOption(e),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notify(type, data) {
|
|
||||||
switch (type) {
|
|
||||||
case DataEvent.PAGE_UPDATED:
|
|
||||||
document.getElementById('submit-update').classList.add('icon-hide');
|
|
||||||
document.getElementById('submit-good').classList.remove('icon-hide');
|
|
||||||
document.getElementById('edit-update').classList.remove('submit-start');
|
|
||||||
document.getElementById('edit-update').classList.add('submit-cool');
|
|
||||||
setTimeout(() => {
|
|
||||||
document
|
|
||||||
.getElementById('submit-update')
|
|
||||||
.classList.remove('icon-hide');
|
|
||||||
document.getElementById('submit-good').classList.add('icon-hide');
|
|
||||||
document.getElementById('edit-update').classList.add('submit-start');
|
|
||||||
document
|
|
||||||
.getElementById('edit-update')
|
|
||||||
.classList.remove('submit-cool');
|
|
||||||
}, 2000);
|
|
||||||
break;
|
|
||||||
case DataEvent.PAGE_ADDED:
|
|
||||||
// do nothing
|
|
||||||
break;
|
|
||||||
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE: {
|
|
||||||
let len = this.textEditor.value.length;
|
|
||||||
let start = this.textEditor.selectionStart;
|
|
||||||
let end = this.textEditor.selectionEnd;
|
|
||||||
let insert = '![image alt text](' + data + ')';
|
|
||||||
|
|
||||||
this.textEditor.value =
|
|
||||||
this.textEditor.value.substring(0, start) +
|
|
||||||
insert +
|
|
||||||
this.textEditor.value.substring(end, len);
|
|
||||||
document.getElementById('edit').dispatchEvent(new Event('input'));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
handleEditorOption(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
let len = this.textEditor.value.length;
|
|
||||||
let start = this.textEditor.selectionStart;
|
|
||||||
let end = this.textEditor.selectionEnd;
|
|
||||||
|
|
||||||
let selectedText = this.textEditor.value.substring(start, end);
|
|
||||||
let insert = '';
|
|
||||||
switch (e.target.id) {
|
|
||||||
case 'edit-bold':
|
|
||||||
insert = '**' + selectedText + '**';
|
|
||||||
this.textEditor.value =
|
|
||||||
this.textEditor.value.substring(0, start) +
|
|
||||||
insert +
|
|
||||||
this.textEditor.value.substring(end, len);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'edit-italic':
|
|
||||||
insert = '*' + selectedText + '*';
|
|
||||||
//console.log(this.textEditor);
|
|
||||||
this.textEditor.value =
|
|
||||||
this.textEditor.value.substring(0, start) +
|
|
||||||
insert +
|
|
||||||
this.textEditor.value.substring(end, len);
|
|
||||||
break;
|
|
||||||
case 'edit-strikethrough':
|
|
||||||
insert = '~~' + selectedText + '~~';
|
|
||||||
this.textEditor.value =
|
|
||||||
this.textEditor.value.substring(0, start) +
|
|
||||||
insert +
|
|
||||||
this.textEditor.value.substring(end, len);
|
|
||||||
break;
|
|
||||||
case 'edit-header1':
|
|
||||||
insert = '# ' + selectedText + '\n';
|
|
||||||
this.textEditor.value =
|
|
||||||
this.textEditor.value.substring(0, start) +
|
|
||||||
insert +
|
|
||||||
this.textEditor.value.substring(end, len);
|
|
||||||
break;
|
|
||||||
case 'edit-header2':
|
|
||||||
insert = '## ' + selectedText + '\n';
|
|
||||||
this.textEditor.value =
|
|
||||||
this.textEditor.value.substring(0, start) +
|
|
||||||
insert +
|
|
||||||
this.textEditor.value.substring(end, len);
|
|
||||||
break;
|
|
||||||
case 'edit-header3':
|
|
||||||
insert = '### ' + selectedText + '\n';
|
|
||||||
this.textEditor.value =
|
|
||||||
this.textEditor.value.substring(0, start) +
|
|
||||||
insert +
|
|
||||||
this.textEditor.value.substring(end, len);
|
|
||||||
break;
|
|
||||||
case 'edit-link':
|
|
||||||
{
|
|
||||||
let url = prompt("Let's get that url, boss");
|
|
||||||
let link = url.toLowerCase();
|
|
||||||
insert = '[' + selectedText + '](' + link + ')';
|
|
||||||
this.textEditor.value =
|
|
||||||
this.textEditor.value.substring(0, start) +
|
|
||||||
insert +
|
|
||||||
this.textEditor.value.substring(end, len);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'edit-image':
|
|
||||||
//this.caretPos = position(this.textEditor).pos;
|
|
||||||
this.emitEvent(EditorEvent.EDITOR_UPLOAD_POST_IMAGE);
|
|
||||||
break;
|
|
||||||
case 'submit-save':
|
|
||||||
case 'edit-save':
|
|
||||||
this.emitEvent(EditorEvent.EDITOR_SAVE);
|
|
||||||
break;
|
|
||||||
case 'submit-update':
|
|
||||||
case 'edit-update':
|
|
||||||
this.emitEvent(EditorEvent.EDITOR_UPDATE);
|
|
||||||
break;
|
|
||||||
case 'edit-delete':
|
|
||||||
this.emitEvent(EditorEvent.EDITOR_DELETE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//do stuff
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
document.getElementById('edit').dispatchEvent(new Event('input'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default TextEditor;
|
|
|
@ -1,95 +0,0 @@
|
||||||
export default class DataUtils {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
|
|
||||||
imgLoad(url) {
|
|
||||||
'use strict';
|
|
||||||
// Create new promise with the Promise() constructor;
|
|
||||||
// This has as its argument a function with two parameters, resolve and reject
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
// Standard XHR to load an image
|
|
||||||
var request = new XMLHttpRequest();
|
|
||||||
request.open('GET', url);
|
|
||||||
request.responseType = 'blob';
|
|
||||||
// When the request loads, check whether it was successful
|
|
||||||
request.onload = function () {
|
|
||||||
if (request.status === 200) {
|
|
||||||
// If successful, resolve the promise by passing back the request response
|
|
||||||
resolve(request.response);
|
|
||||||
} else {
|
|
||||||
// If it fails, reject the promise with a error message
|
|
||||||
reject(
|
|
||||||
new Error(
|
|
||||||
"Image didn't load successfully; error code: " +
|
|
||||||
request.status +
|
|
||||||
' ' +
|
|
||||||
request.statusText
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
request.onerror = function () {
|
|
||||||
// Also deal with the case when the entire request fails to begin with
|
|
||||||
// This is probably a network error, so reject the promise with an appropriate message
|
|
||||||
reject(new Error('There was a network error.'));
|
|
||||||
};
|
|
||||||
// Send the request
|
|
||||||
request.send();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
loadImage(src) {
|
|
||||||
'use strict';
|
|
||||||
let self = this;
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
// Get a reference to the body element, and create a new image object
|
|
||||||
var myImage = new Image();
|
|
||||||
myImage.crossOrigin = ''; // or "anonymous"
|
|
||||||
// Call the function with the URL we want to load, but then chain the
|
|
||||||
// promise then() method on to the end of it. This contains two callbacks
|
|
||||||
self.imgLoad(src).then(
|
|
||||||
function (response) {
|
|
||||||
// The first runs when the promise resolves, with the request.reponse specified within the resolve() method.
|
|
||||||
var imageURL = window.URL.createObjectURL(response);
|
|
||||||
resolve(imageURL);
|
|
||||||
//$('background-content').setStyle('background-image', 'url('+imageURL+')') //myImage.src = imageURL;
|
|
||||||
//console.log(imageURL);
|
|
||||||
//body.appendChild(myImage);
|
|
||||||
// The second runs when the promise is rejected, and logs the Error specified with the reject() method.
|
|
||||||
},
|
|
||||||
function (Error) {
|
|
||||||
reject(Error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a function to convert the serialize and convert the form data to JSON
|
|
||||||
* @param : $('#form_example');
|
|
||||||
* @return a JSON Stringify
|
|
||||||
*/
|
|
||||||
formDataToJSON(form) {
|
|
||||||
let object = {};
|
|
||||||
let formData = new FormData(form);
|
|
||||||
formData.forEach((value, key) => {
|
|
||||||
if (!object.hasOwnProperty(key)) {
|
|
||||||
object[key] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!Array.isArray(object[key])) {
|
|
||||||
object[key] = [object[key]];
|
|
||||||
}
|
|
||||||
object[key].push(value);
|
|
||||||
});
|
|
||||||
//let json = JSON.stringify(object);
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
class StringUtils {
|
|
||||||
//--------------------------
|
|
||||||
// constructor
|
|
||||||
//--------------------------
|
|
||||||
constructor() {}
|
|
||||||
//--------------------------
|
|
||||||
// methods
|
|
||||||
//--------------------------
|
|
||||||
cleanString(string) {
|
|
||||||
var clean = string
|
|
||||||
.replace(/(^\-+|[^a-zA-Z0-9\/_| -]+|\-+$)/g, '')
|
|
||||||
.toLowerCase()
|
|
||||||
.replace(/[\/_| -]+/g, '-');
|
|
||||||
return clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
decodeHTML(string, quote_style) {
|
|
||||||
var optTemp = 0,
|
|
||||||
i = 0,
|
|
||||||
noquotes = false;
|
|
||||||
if (typeof quote_style === 'undefined') {
|
|
||||||
quote_style = 2;
|
|
||||||
}
|
|
||||||
string = string
|
|
||||||
.toString()
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>');
|
|
||||||
var OPTS = {
|
|
||||||
ENT_NOQUOTES: 0,
|
|
||||||
ENT_HTML_QUOTE_SINGLE: 1,
|
|
||||||
ENT_HTML_QUOTE_DOUBLE: 2,
|
|
||||||
ENT_COMPAT: 2,
|
|
||||||
ENT_QUOTES: 3,
|
|
||||||
ENT_IGNORE: 4
|
|
||||||
};
|
|
||||||
if (quote_style === 0) {
|
|
||||||
noquotes = true;
|
|
||||||
}
|
|
||||||
if (typeof quote_style !== 'number') {
|
|
||||||
// Allow for a single string or an array of string flags
|
|
||||||
quote_style = [].concat(quote_style);
|
|
||||||
for (i = 0; i < quote_style.length; i++) {
|
|
||||||
// Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
|
|
||||||
if (OPTS[quote_style[i]] === 0) {
|
|
||||||
noquotes = true;
|
|
||||||
} else if (OPTS[quote_style[i]]) {
|
|
||||||
optTemp = optTemp | OPTS[quote_style[i]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
quote_style = optTemp;
|
|
||||||
}
|
|
||||||
if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
|
|
||||||
string = string.replace(/�*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
|
|
||||||
// string = string.replace(/'|�*27;/g, "'"); // This would also be useful here, but not a part of PHP
|
|
||||||
}
|
|
||||||
if (!noquotes) {
|
|
||||||
string = string.replace(/"/g, '"');
|
|
||||||
}
|
|
||||||
// Put this in last place to avoid escape being double-decoded
|
|
||||||
string = string.replace(/&/g, '&');
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------
|
|
||||||
// event handlers
|
|
||||||
//--------------------------
|
|
||||||
}
|
|
||||||
export default StringUtils;
|
|
Loading…
Reference in a new issue