plugged in prettier and eslint, deep cleaned code base

sql-version-freeze
Ro 6 years ago
parent cc19e14a25
commit 5decfa92e2

@ -0,0 +1,69 @@
{
"parserOptions": {
"ecmaVersion": 7,
"sourceType": "module",
"ecmaFeatures": {}
},
"rules": {
"constructor-super": 2,
"for-direction": 2,
"getter-return": 2,
"no-case-declarations": 2,
"no-class-assign": 2,
"no-compare-neg-zero": 2,
"no-cond-assign": 2,
"no-console": 2,
"no-const-assign": 2,
"no-constant-condition": 2,
"no-control-regex": 1,
"no-debugger": 2,
"no-delete-var": 2,
"no-dupe-args": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-empty": 2,
"no-empty-character-class": 2,
"no-empty-pattern": 2,
"no-ex-assign": 2,
"no-extra-boolean-cast": 2,
"no-extra-semi": 2,
"no-fallthrough": 2,
"no-func-assign": 2,
"no-global-assign": 2,
"no-inner-declarations": 2,
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-mixed-spaces-and-tabs": 2,
"no-new-symbol": 2,
"no-obj-calls": 2,
"no-octal": 2,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-self-assign": 2,
"no-sparse-arrays": 2,
"no-this-before-super": 2,
"no-undef": 2,
"no-unexpected-multiline": 2,
"no-unreachable": 2,
"no-unsafe-finally": 2,
"no-unsafe-negation": 2,
"no-unused-labels": 2,
"no-unused-vars": 2,
"no-useless-escape": 1,
"require-yield": 2,
"use-isnan": 2,
"valid-typeof": 2,
"no-duplicate-imports": 2
},
"env": {
"node": true,
"browser": true,
"es6": true
},
"globals": {
"_": false,
"hljs": false,
"Sortable": false
}
}

@ -0,0 +1,5 @@
.babelrc
README.md
*.pug
*.styl

@ -0,0 +1,17 @@
{
"arrowParens": "avoid",
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxBracketSameLine": false,
"jsxSingleQuote": true,
"parser": "babel",
"proseWrap": "preserve",
"requirePragma": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"useTabs": true,
"tabWidth": 4,
"printWidth": 100
}

@ -2,20 +2,11 @@ import DateUtils from '../../tools/utilities/DateUtils';
import StringUtils from '../../tools/utilities/StringUtils'; import StringUtils from '../../tools/utilities/StringUtils';
import * as DataEvent from '../../tools/events/DataEvent'; import * as DataEvent from '../../tools/events/DataEvent';
import sanitize from 'sanitize-html'; import sanitize from 'sanitize-html';
import RightsManager, import RightsManager, {
{ TASK_CREATE,
TASK_CREATE, TASK_UPDATE,
TASK_UPDATE, OBJECT_POST
TASK_READ, } from '../../tools/utilities/RightsManager';
TASK_DELETE,
OBJECT_CLIENT_ADMIN,
OBJECT_CLIENT_USER,
OBJECT_PROJECT_CLIENT,
OBJECT_PROJECT_FOLIO,
OBJECT_BOOKMARK,
OBJECT_POST
}
from '../../tools/utilities/RightsManager';
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const multer = require('multer'); const multer = require('multer');
@ -24,227 +15,182 @@ const fs = require('fs-extra');
const Models = require('../../models'); const Models = require('../../models');
const dateUtils = new DateUtils(); const dateUtils = new DateUtils();
const rightsManager = new RightsManager(); const rightsManager = new RightsManager();
const uploadPath = "./content/blog-images/" + dateUtils.getDate('year', new Date()) + "/" + dateUtils.getDate('month', new Date()); const uploadPath =
'./content/blog-images/' +
dateUtils.getDate('year', new Date()) +
'/' +
dateUtils.getDate('month', new Date());
const Sequelize = require('sequelize'); const Sequelize = require('sequelize');
const Op = Sequelize.Op; const Op = Sequelize.Op;
const _ = require('lodash'); const _ = require('lodash');
fs.ensureDir(uploadPath, function(err) fs.ensureDir(uploadPath, () => {
{ //console.log(err) // => null
//console.log(err) // => null // dir has now been created, including the directory it is to be placed in
// dir has now been created, including the directory it is to be placed in
})
var storage = multer.diskStorage(
{
destination: function(req, file, cb)
{
cb(null, uploadPath)
},
filename: function(req, file, cb)
{
var splice = file.originalname.split(':');
cb(null, splice[0]);
}
}); });
var feature_upload = multer( var storage = multer.diskStorage({
{ destination: function(req, file, cb) {
storage: storage cb(null, uploadPath);
},
filename: function(req, file, cb) {
var splice = file.originalname.split(':');
cb(null, splice[0]);
}
});
var feature_upload = multer({
storage: storage
}).array('feature_image'); }).array('feature_image');
var post_upload = multer( var post_upload = multer({
{ storage: storage
storage: storage
}).array('post_image'); }).array('post_image');
//** SYNC POSTS */ //** SYNC POSTS */
router.post("/sync", (req, res, next) => router.post('/sync', (req, res) => {
{ let payload = req.body;
let payload = req.body; Models.User.findById(req.session.user.id).then(user => {
Models.User.findById(req.session.user.id).then((user) => if (rightsManager.check(user.role, OBJECT_POST, TASK_UPDATE)) {
{ for (let index = 0; index < payload.length; index++) {
if (rightsManager.check(user.role, OBJECT_POST, TASK_UPDATE)) const item = payload[index];
{ Models.FreshPost.findOne({
for (let index = 0; index < payload.length; index++) where: {
{ post: {
const item = payload[index]; [Op.contains]: {
Models.FreshPost.findOne( uuid: item.post.uuid
{ }
where: }
{ }
"post": })
{ .then(found => {
[Op.contains]: let buffed = sanitize(item.post.plaintext, {
{ allowedTags: ['del', 'a', 'iframe', 'img'],
uuid: item.post.uuid allowedAttributes: {
} a: ['href', 'name', 'target'],
} img: ['src'],
} iframe: [
}).then(found => 'height',
{ 'width',
let buffed = sanitize(item.post.plaintext, 'src',
{ 'frameborder',
allowedTags: ['del', 'a', 'iframe', 'img', ], 'allow',
allowedAttributes: 'allowfullscreen'
{ ]
a: ['href', 'name', 'target'], }
img: ['src'], });
iframe: ['height', 'width', 'src', 'frameborder', 'allow', 'allowfullscreen'] buffed = new StringUtils().decodeHTML(buffed);
} item.post.plaintext = buffed;
}) item.post.html = md.render(buffed, {
buffed = new StringUtils().decodeHTML(buffed); html: true,
item.post.plaintext = buffed; xhtmlOut: true
item.post.html = md.render(buffed, });
{ if (!_.isEqual(item.post, found.post)) {
html: true, found
xhtmlOut: true, .update(item)
}); .then(() => {
if (!_.isEqual(item.post, found.post)) //console.log('UPDATED', updated);
{ })
found.update(item).then(updated => .catch(() => {
{ //console.log("***ERROR***", err);
console.log("UPDATED", updated); });
}).catch(err => } else {
{ //chilld
//console.log("***ERROR***", err); }
}) })
} .catch(() => {
else //console.log("***ERRRORZ****", err);
{ Models.FreshPost.create(item).then(() => {
//chilld //console.log(fresh)
} });
}).catch(err => });
{ }
//console.log("***ERRRORZ****", err); res.json({
Models.FreshPost.create(item).then(fresh => message: 'postsSynced'
{ });
//console.log(fresh) } else {
}) res.json({
}) message: "Nah. You can't do that. Talk to the admin, sport."
} });
res.json( }
{ });
message: "postsSynced" });
}); router.get('/json', function(req, res) {
} Models.FreshPost.findAll({
else order: [['id', 'DESC']]
{ })
res.json( .then(function(posts) {
{ let newlist = [];
message: "Nah. You can't do that. Talk to the admin, sport." for (let index = 0; index < posts.length; index++) {
}); let item = posts[index].post;
} if (typeof item.deleted == 'undefined' || item.deleted == false) {
}); newlist.push(posts[index]);
}) } else {
router.get('/json', function(req, res, next) continue;
{ }
Models.FreshPost.findAll( }
{ res.json(newlist);
order: [ })
['id', 'DESC'] .catch(() => {
] //next(err);
}).then(function(posts) });
{ });
let newlist = [];
for (let index = 0; index < posts.length; index++)
{
let item = posts[index].post;
if (typeof item.deleted == 'undefined' || item.deleted == false)
{
newlist.push(posts[index])
}
else
{
continue
}
}
res.json(newlist)
}).catch(function(err)
{
//next(err);
})
})
/*** /***
POST IMAGE POST IMAGE
*/ */
router.post('/add-post-image', function(req, res, next) router.post('/add-post-image', function(req, res) {
{ //console.log(req.body);
//console.log(req.body); if (!req.session.user)
if (!req.session.user) return res.json( return res.json({
{ message: 'You need to be logged in, champ.'
message: "You need to be logged in, champ." });
}); Models.User.findById(req.session.user.id).then(user => {
Models.User.findById(req.session.user.id).then((user) => if (rightsManager.check(user.role, OBJECT_POST, TASK_CREATE)) {
{ post_upload(req, res, function(err) {
if (rightsManager.check(user.role, OBJECT_POST, TASK_CREATE)) if (err) {
{ //console.log('Error in Saving Entry: ' + err);
post_upload(req, res, function(err) res.json({
{ message: err
if (err) });
{ throw err;
//console.log('Error in Saving Entry: ' + err); } else {
res.json( var postImage = req.files[0].path;
{ return res.json({
message: err message: DataEvent.POST_IMAGE_ADDED,
}); url: postImage.substr(7, postImage.length)
throw err; });
} }
else });
{ } else {
var postImage = req.files[0].path; res.json({
return res.json( message: "Nah. You can't do that. Talk to the admin, sport."
{ });
message: DataEvent.POST_IMAGE_ADDED, }
url: postImage.substr(7, postImage.length) });
});
}
});
}
else
{
res.json(
{
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
}); });
router.post('/add-feature-image', function(req, res, next) router.post('/add-feature-image', function(req, res) {
{ //console.log(req.body);
//console.log(req.body); if (!req.session.user)
if (!req.session.user) return res.json( return res.json({
{ message: 'You need to be logged in, champ.'
message: "You need to be logged in, champ." });
}); Models.User.findById(req.session.user.id).then(user => {
Models.User.findById(req.session.user.id).then((user) => if (rightsManager.check(user.role, OBJECT_POST, TASK_CREATE)) {
{ feature_upload(req, res, function(err) {
if (rightsManager.check(user.role, OBJECT_POST, TASK_CREATE)) if (err) {
{ //console.log('Error in Saving Entry: ' + err);
feature_upload(req, res, function(err) res.json({
{ message: err
if (err) });
{ throw err;
//console.log('Error in Saving Entry: ' + err); } else {
res.json( var postImage = req.files[0].path;
{ return res.json({
message: err message: DataEvent.FEATURE_IMAGE_ADDED,
}); url: postImage.substr(7, postImage.length)
throw err; });
} }
else });
{ } else {
var postImage = req.files[0].path; res.json({
return res.json( message: "Nah. You can't do that. Talk to the admin, sport."
{ });
message: DataEvent.FEATURE_IMAGE_ADDED, }
url: postImage.substr(7, postImage.length) });
});
}
});
}
else
{
res.json(
{
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
}); });
module.exports = router; module.exports = router;

@ -1,21 +1,11 @@
import DateUtils from '../../tools/utilities/DateUtils'; import DateUtils from '../../tools/utilities/DateUtils';
import StringUtils from '../../tools/utilities/StringUtils';
import * as DataEvent from '../../tools/events/DataEvent'; import * as DataEvent from '../../tools/events/DataEvent';
import RightsManager, import RightsManager, {
{ TASK_CREATE,
TASK_CREATE, TASK_UPDATE,
TASK_UPDATE, OBJECT_POST,
TASK_READ, OBJECT_SETTINGS
TASK_DELETE, } from '../../tools/utilities/RightsManager';
OBJECT_CLIENT_ADMIN,
OBJECT_CLIENT_USER,
OBJECT_PROJECT_CLIENT,
OBJECT_PROJECT_FOLIO,
OBJECT_BOOKMARK,
OBJECT_POST,
OBJECT_SETTINGS
}
from '../../tools/utilities/RightsManager';
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const multer = require('multer'); const multer = require('multer');
@ -23,252 +13,200 @@ const fs = require('fs-extra');
const Models = require('../../models'); const Models = require('../../models');
const dateUtils = new DateUtils(); const dateUtils = new DateUtils();
const rightsManager = new RightsManager(); const rightsManager = new RightsManager();
const uploadPath = "./content/user-images/" + dateUtils.getDate('year', new Date()) + "/" + dateUtils.getDate('month', new Date()); const uploadPath =
const Sequelize = require('sequelize'); './content/user-images/' +
const Op = Sequelize.Op; dateUtils.getDate('year', new Date()) +
const _ = require('lodash'); '/' +
fs.ensureDir(uploadPath, function(err) dateUtils.getDate('month', new Date());
{ fs.ensureDir(uploadPath, () => {
//console.log(err) // => null //console.log(err) // => null
// dir has now been created, including the directory it is to be placed in // dir has now been created, including the directory it is to be placed in
})
var storage = multer.diskStorage(
{
destination: function(req, file, cb)
{
cb(null, uploadPath)
},
filename: function(req, file, cb)
{
var splice = file.originalname.split(':');
cb(null, splice[0]);
}
}); });
var avatar_upload = multer( var storage = multer.diskStorage({
{ destination: function(req, file, cb) {
storage: storage cb(null, uploadPath);
},
filename: function(req, file, cb) {
var splice = file.originalname.split(':');
cb(null, splice[0]);
}
});
var avatar_upload = multer({
storage: storage
}).array('avatar_upload'); }).array('avatar_upload');
var background_upload = multer( var background_upload = multer({
{ storage: storage
storage: storage
}).array('background_upload'); }).array('background_upload');
//** SYNC POSTS */ //** SYNC POSTS */
router.post("/sync", (req, res, next) => router.post('/sync', (req, res) => {
{ let payload = req.body;
let payload = req.body; Models.User.findById(req.session.user.id).then(user => {
Models.User.findById(req.session.user.id).then((user) => if (rightsManager.check(user.role, OBJECT_SETTINGS, TASK_UPDATE)) {
{ fs.readJson('config/site-settings.json')
if (rightsManager.check(user.role, OBJECT_SETTINGS, TASK_UPDATE)) .then(obj => {
{ if (user.hande != payload.handle || user.email != payload.email) {
fs.readJson('config/site-settings.json').then(obj => user.update({
{ handle: payload.handle,
if (user.hande != payload.handle || user.email != payload.email) email: payload.email
{ })
user.update( .then(() => {
{ //console.log('UPDATED');
handle: payload.handle, })
email: payload.email .catch(() => {
}).then(updated => //console.log('ERR', err);
{ });
console.log("UPDATED") } else {
}).catch(err => //console.log('USER NOT UPDATED');
{ }
console.log("ERR", err); obj.url = payload.url;
}) obj.title = payload.title;
} obj.description = payload.descriptions;
else obj.private = payload.private;
{ obj.theme = payload.theme;
console.log("USER NOT UPDATED") obj.background = payload.background; //TODO: make this url relative
} //mail stuff
obj.url = payload.url; obj.email.active = payload.mailSettings.activeProtocol;
obj.title = payload.title; obj.email.smtp.domain = payload.mailSettings.smtp.domain;
obj.description = payload.descriptions; obj.email.smtp.email = payload.mailSettings.smtp.email;
obj.private = payload.private; obj.email.smtp.password = payload.mailSettings.smtp.password;
obj.theme = payload.theme; obj.email.mailgun.domain = payload.mailSettings.mailgun.domain;
obj.background = payload.background; //TODO: make this url relative obj.email.mailgun['api-key'] = payload.mailSettings.mailgun.key;
//mail stuff fs.writeJson('config/site-settings.json', obj)
obj.email.active = payload.mailSettings.activeProtocol; .then(() => {
obj.email.smtp.domain = payload.mailSettings.smtp.domain; res.json({
obj.email.smtp.email = payload.mailSettings.smtp.email; message: DataEvent.SETTINGS_UPDATED
obj.email.smtp.password = payload.mailSettings.smtp.password; });
obj.email.mailgun.domain = payload.mailSettings.mailgun.domain; })
obj.email.mailgun['api-key'] = payload.mailSettings.mailgun.key; .catch(() => {
fs.writeJson('config/site-settings.json', obj).then(() => //console.error(err);
{ });
res.json( })
{ .catch(() => {
message: DataEvent.SETTINGS_UPDATED //console.error(err);
}); });
}).catch(err => } else {
{ res.json({
console.error(err) message: "Nah. You can't do that. Talk to the admin, sport."
}) });
}).catch(err => }
{ });
console.error(err) });
})
}
else
{
res.json(
{
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
})
router.get('/nav', function(req, res, next)
{
fs.readJson('config/site-settings.json').then(obj =>
{
fs.writeJson('config/site-settings.json', obj).then(() =>
{
res.json(obj.menu);
}).catch(err =>
{
console.error(err)
})
}).catch(err =>
{
console.error(err)
})
})
router.post("/nav-sync", (req, res, next) => router.get('/nav', function(req, res) {
{ fs.readJson('config/site-settings.json')
let payload = req.body; .then(obj => {
Models.User.findById(req.session.user.id).then((user) => fs.writeJson('config/site-settings.json', obj)
{ .then(() => {
if (rightsManager.check(user.role, OBJECT_SETTINGS, TASK_UPDATE)) res.json(obj.menu);
{ })
fs.readJson('config/site-settings.json').then(obj => .catch(() => {
{ //console.error(err);
});
obj.menu = payload; })
fs.writeJson('config/site-settings.json', obj).then(() => .catch(() => {
{ //console.error(err);
res.json( });
{ });
message: DataEvent.SETTINGS_UPDATED
});
}).catch(err =>
{
console.error(err)
})
}).catch(err =>
{
console.error(err)
})
}
else
{
res.json(
{
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
})
router.post('/nav-sync', (req, res) => {
let payload = req.body;
Models.User.findById(req.session.user.id).then(user => {
if (rightsManager.check(user.role, OBJECT_SETTINGS, TASK_UPDATE)) {
fs.readJson('config/site-settings.json')
.then(obj => {
obj.menu = payload;
fs.writeJson('config/site-settings.json', obj)
.then(() => {
res.json({
message: DataEvent.SETTINGS_UPDATED
});
})
.catch(() => {
//console.error(err);
});
})
.catch(() => {
//console.error(err);
});
} else {
res.json({
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
});
/*** /***
UPLOAD AVATAR UPLOAD AVATAR
*/ */
router.post('/add-avatar', function(req, res, next) router.post('/add-avatar', function(req, res) {
{ //console.log(req.body);
//console.log(req.body); if (!req.session.user)
if (!req.session.user) return res.json( return res.json({
{ message: 'You need to be logged in, champ.'
message: "You need to be logged in, champ." });
}); Models.User.findById(req.session.user.id).then(user => {
Models.User.findById(req.session.user.id).then((user) => if (rightsManager.check(user.role, OBJECT_POST, TASK_CREATE)) {
{ avatar_upload(req, res, function(err) {
if (rightsManager.check(user.role, OBJECT_POST, TASK_CREATE)) if (err) {
{ res.json({
avatar_upload(req, res, function(err) message: err
{ });
if (err) throw err;
{ } else {
res.json( var avatar = req.files[0].path;
{ user.update({
message: err avatar: avatar.substr(7, avatar.length)
}); })
throw err; .then(updated => {
} req.session.user = updated;
else })
{ .catch(() => {
var avatar = req.files[0].path; //console.log('ERR', err);
user.update( });
{ return res.json({
avatar: avatar.substr(7, avatar.length) message: DataEvent.AVATAR_UPLOADED,
}).then(updated => url: avatar.substr(7, avatar.length)
{ });
}
req.session.user = updated; });
}).catch(err => } else {
{ res.json({
console.log("ERR", err); message: "Nah. You can't do that. Talk to the admin, sport."
}) });
return res.json( }
{ });
message: DataEvent.AVATAR_UPLOADED,
url: avatar.substr(7, avatar.length)
});
}
});
}
else
{
res.json(
{
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
}); });
/*** /***
UPLOAD FEATURE BACKGROUND UPLOAD FEATURE BACKGROUND
*/ */
router.post('/add-feature-background', function(req, res, next) router.post('/add-feature-background', function(req, res) {
{ //console.log(req.body);
//console.log(req.body); if (!req.session.user)
if (!req.session.user) return res.json( return res.json({
{ message: 'You need to be logged in, champ.'
message: "You need to be logged in, champ." });
}); Models.User.findById(req.session.user.id).then(user => {
Models.User.findById(req.session.user.id).then((user) => if (rightsManager.check(user.role, OBJECT_POST, TASK_CREATE)) {
{ background_upload(req, res, function(err) {
if (rightsManager.check(user.role, OBJECT_POST, TASK_CREATE)) if (err) {
{ res.json({
background_upload(req, res, function(err) message: err
{ });
if (err) throw err;
{ } else {
res.json( var bgImage = req.files[0].path;
{ return res.json({
message: err message: DataEvent.SITE_BACKGROUND_UPLOADED,
}); url: bgImage.substr(7, bgImage.length)
throw err; });
} }
else });
{ } else {
var bgImage = req.files[0].path; res.json({
return res.json( message: "Nah. You can't do that. Talk to the admin, sport."
{ });
message: DataEvent.SITE_BACKGROUND_UPLOADED, }
url: bgImage.substr(7, bgImage.length) });
});
}
});
}
else
{
res.json(
{
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
}); });
module.exports = router; module.exports = router;

@ -4,79 +4,71 @@ var nodemailer = require('nodemailer');
var mg = require('nodemailer-mailgun-transport'); var mg = require('nodemailer-mailgun-transport');
const fs = require('fs-extra'); const fs = require('fs-extra');
const pug = require('pug'); const pug = require('pug');
router.post('/', function(req, res, next) router.post('/', function(req, res) {
{ fs.readJson('config/site-settings.json')
fs.readJson('config/site-settings.json').then(settings => .then(settings => {
{ let transport = '';
let transport = '' var auth = '';
switch (settings.email.active) switch (settings.email.active) {
{ case 'option-smtp':
case "option-smtp": auth = {
var auth = { host: settings.email.smtp.domain,
host: settings.email.smtp.domain, port: 587,
port: 587, secure: false,
secure: false, auth: {
auth: type: 'login',
{ email: settings.email.smtp,
type:"login", password: settings.email.smtp.password
email: settings.email.smtp, }
password: settings.email.smtp.password };
} transport = nodemailer.createTransport(auth);
} break;
transport = nodemailer.createTransport((auth)); case 'option-mg':
break; auth = {
case "option-mg": auth: {
var auth = { api_key: settings.email.mailgun['api-key'],
auth: domain: settings.email.mailgun.domain
{ }
api_key: settings.email.mailgun['api-key'], };
domain: settings.email.mailgun.domain transport = nodemailer.createTransport(mg(auth));
} break;
} }
transport = nodemailer.createTransport(mg(auth)); let render = pug.compileFile('themes/dash/email/base.pug');
break let html = render({
} title: settings.title,
let render = pug.compileFile('themes/dash/email/base.pug'); header: 'a note from ' + settings.title,
let html = render( content: req.body.content,
{ footer: 'powered by fipamo'
title: settings.title, });
header: "a note from " + settings.title, transport.sendMail(
content: req.body.content, {
footer: "powered by fipamo" from: 'control@playvico.us',
}) to: 'are0h@protonmail.com', // An array if you have multiple recipients.
transport.sendMail( subject: 'Hey beautiful',
{ //You can use "html:" to send HTML email content. It's magic!
from: 'control@playvico.us', html: html
to: 'are0h@protonmail.com', // An array if you have multiple recipients. //You can use "text:" to send plain-text content. It's oldschool!
subject: 'Hey beautiful', //text: 'Mailgun rocks, pow pow!'
//You can use "html:" to send HTML email content. It's magic! },
html: html function(err, info) {
//You can use "text:" to send plain-text content. It's oldschool! if (err) {
//text: 'Mailgun rocks, pow pow!' //console.log(err);
}, function(err, info) res.json({
{ message: 'MAIL ERROR',
if (err) desc: err
{ });
console.log(err) } else {
res.json( //console.log(info);
{ res.json({
message: "MAIL ERROR", message: 'MAIL SENT',
desc: err desc: info
}); });
} }
else }
{ );
console.log(info) })
res.json( .catch(() => {
{ //console.error(err);
message: "MAIL SENT", });
desc: info
});
}
});
}).catch(err =>
{
console.error(err)
})
}); });
module.exports = router; module.exports = router;

@ -1,33 +1,37 @@
module.exports = function (sequelize, DataTypes) { module.exports = function(sequelize, DataTypes) {
var FreshPost = sequelize.define('FreshPost', { var FreshPost = sequelize.define(
post: { 'FreshPost',
type: DataTypes.JSONB {
} post: {
}, { type: DataTypes.JSONB
timestamps: false, }
},
{
timestamps: false,
// don't delete database entries but set the newly added attribute deletedAt // don't delete database entries but set the newly added attribute deletedAt
// to the current date (when deletion was done). paranoid will only work if // to the current date (when deletion was done). paranoid will only work if
// timestamps are enabled // timestamps are enabled
paranoid: false, paranoid: false,
// don't use camelcase for automatically added attributes but underscore style // don't use camelcase for automatically added attributes but underscore style
// so updatedAt will be updated_at // so updatedAt will be updated_at
underscored: true, underscored: true,
// disable the modification of table names; By default, sequelize will automatically // disable the modification of table names; By default, sequelize will automatically
// transform all passed model names (first parameter of define) into plural. // transform all passed model names (first parameter of define) into plural.
// if you don't want that, set the following // if you don't want that, set the following
freezeTableName: false, freezeTableName: false,
// define the table's name // define the table's name
tableName: 'FreshPosts', tableName: 'FreshPosts',
// Enable optimistic locking. When enabled, sequelize will add a version count attriubte // Enable optimistic locking. When enabled, sequelize will add a version count attriubte
// to the model and throw an OptimisticLockingError error when stale instances are saved. // to the model and throw an OptimisticLockingError error when stale instances are saved.
// Set to true or a string with the attribute name you want to use to enable. // Set to true or a string with the attribute name you want to use to enable.
version: false version: false
}); }
);
return FreshPost; return FreshPost;
}; };

@ -10,25 +10,24 @@ const db = {};
let sequelize; let sequelize;
if (config.use_env_variable) { if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config); sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else { } else {
sequelize = new Sequelize(config.database, config.username, config.password, config); sequelize = new Sequelize(config.database, config.username, config.password, config);
} }
fs fs.readdirSync(__dirname)
.readdirSync(__dirname) .filter(file => {
.filter(file => { return file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js';
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); })
}) .forEach(file => {
.forEach(file => { const model = sequelize['import'](path.join(__dirname, file));
const model = sequelize['import'](path.join(__dirname, file)); db[model.name] = model;
db[model.name] = model; });
});
Object.keys(db).forEach(modelName => { Object.keys(db).forEach(modelName => {
if (db[modelName].associate) { if (db[modelName].associate) {
db[modelName].associate(db); db[modelName].associate(db);
} }
}); });
db.sequelize = sequelize; db.sequelize = sequelize;

@ -1,98 +1,80 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const Models = require('../../models'); const Models = require('../../models');
const fs = require("fs-extra"); const fs = require('fs-extra');
const _ = require('lodash'); const _ = require('lodash');
var settings = []; var settings = [];
//-------------------------- //--------------------------
// SETTINGS // SETTINGS
//-------------------------- //--------------------------
router.get('/', function(req, res) router.get('/', function(req, res) {
{ fs.readJson('config/site-settings.json')
fs.readJson('config/site-settings.json').then(obj => .then(obj => {
{ settings = [];
settings = [] settings = obj;
settings = obj; })
}).catch(err => .catch(() => {
{ //console.error(err)
//console.error(err) });
}) if (req.session.user) {
if (req.session.user) Models.User.findById(req.session.user.id).then(() => {
{ Models.FreshPost.findAll({
Models.User.findById(req.session.user.id).then((user) => order: [['id', 'DESC']]
{ })
Models.FreshPost.findAll( .then(posts => {
{ let pages = [];
order: [ if (settings.menu.length == 0) {
['id', 'DESC'] for (let index = 0; index < posts.length; index++) {
] let item = posts[index].post;
}).then(posts => if (item.page == true || item.page == 'true')
{ pages.push({
let pages = [] id: posts[index].id,
if (settings.menu.length == 0) uuid: posts[index].post.uuid,
{ title: posts[index].post.title,
for (let index = 0; index < posts.length; index++) slug: posts[index].post.slug
{ });
let item = posts[index].post; }
if (item.page == true || item.page == "true") pages.push( } else {
{ let newpages = [];
id: posts[index].id, pages = settings.menu;
uuid: posts[index].post.uuid, for (let index = 0; index < posts.length; index++) {
title: posts[index].post.title, let item = posts[index].post;
slug: posts[index].post.slug if (item.page == true || item.page == 'true')
}); newpages.push({
} id: posts[index].id,
} uuid: posts[index].post.uuid,
else title: posts[index].post.title,
{ slug: posts[index].post.slug
let newpages = [] });
pages = settings.menu; }
for (let index = 0; index < posts.length; index++) for (let i = 0; i < newpages.length; i++) {
{ if (
let item = posts[index].post; _.findIndex(pages, function(o) {
if (item.page == true || item.page == "true") newpages.push( return o.id == newpages[i].id;
{ }) != -1
id: posts[index].id, ) {
uuid: posts[index].post.uuid, //console.log("FOUND")
title: posts[index].post.title, } else {
slug: posts[index].post.slug pages.push({
}); id: newpages[i].id,
} uuid: newpages[i].uuid,
for (let i = 0; i < newpages.length; i++) title: newpages[i].title,
{ slug: newpages[i].slug
if (_.findIndex(pages, function(o) });
{ }
return o.id == newpages[i].id; }
}) != -1) }
{ res.render('dash/navigation', {
//console.log("FOUND") pages: pages,
} title: 'Dashboard | Global Nav'
else });
{ })
pages.push( .catch(() => {
{ //console.log('ERROR', err);
id: newpages[i].id, });
uuid: newpages[i].uuid, });
title: newpages[i].title, } else {
slug: newpages[i].slug res.redirect('/@/dashboard');
}); }
}
}
}
res.render('dash/navigation',
{
pages: pages,
title: 'Dashboard | Global Nav'
});
}).catch(err =>
{
console.log("ERROR", err)
})
})
}
else
{
res.redirect('/@/dashboard');
}
}); });
module.exports = router; module.exports = router;

@ -11,123 +11,141 @@ const dateUtils = new DateUtils();
//-------------------------- //--------------------------
// POSTS // POSTS
//-------------------------- //--------------------------
router.get('/:page?', function (req, res) { router.get('/:page?', function(req, res) {
var pageNum = req.params.page; var pageNum = req.params.page;
if (pageNum == "" || pageNum == null) pageNum = 1; if (pageNum == '' || pageNum == null) pageNum = 1;
var offset = ((pageNum * 5) - 5); if (req.session.user) {
if (req.session.user) { Models.FreshPost.findAll({
Models.FreshPost.findAll({ order: [['id', 'DESC']]
order: [ })
['id', 'DESC'] .then(function(posts) {
] let all = [];
}).then(function (posts) { let deleted = [];
let all = []; let published = [];
let deleted = []; let pages = [];
let published = []; let featured = [];
let pages = []; for (let index = 0; index < posts.length; index++) {
let featured = []; let item = posts[index].post;
for (let index = 0; index < posts.length; index++) { if (typeof item.deleted == 'undefined' || item.deleted == false) {
let item = posts[index].post; all.push(posts[index]);
if (typeof item.deleted == 'undefined' || item.deleted == false) { if (item.published == 'true') published.push(posts[index]);
all.push(posts[index]); if (item.page == 'true') pages.push(posts[index]);
if (item.published == 'true') published.push(posts[index]); if (item.featured == 'true') featured.push(posts[index]);
if (item.page == 'true') pages.push(posts[index]); } else {
if (item.featured == 'true') featured.push(posts[index]); deleted.push(posts[index]);
} else { }
deleted.push(posts[index]) }
} var count = Math.round(all.length / 6);
} var pageItems = [];
var count = Math.round(all.length / 6); var itemLimit = 6;
var pageItems = []; var rangeStart = pageNum * itemLimit - itemLimit;
var itemLimit = 6; for (var i = 0; i < itemLimit; i++) {
var rangeStart = (pageNum * itemLimit) - itemLimit; try {
for (var i = 0; i < itemLimit; i++) { if (all[i + rangeStart].id != null) {
try { pageItems.push(all[i + rangeStart]);
if (all[i + rangeStart].id != null) { }
pageItems.push(all[i + rangeStart]); } catch (e) {
} //console.log("NO POST", e)
} catch (e) { }
//console.log("NO POST", e) }
} res.render('dash/posts-index', {
} title: 'Dashbord | Posts',
res.render('dash/posts-index', { mode: 'admin',
title: 'Dashbord | Posts', welcome: 'Your Posts',
mode: 'admin', items: pageItems,
welcome: "Your Posts", page_info: {
items: pageItems, all: all.length,
page_info: { deleted: deleted.length,
all: all.length, published: published.length,
deleted:deleted.length, pages: pages.length,
published: published.length, featured: featured.length
pages: pages.length, },
featured: featured.length page_index: pageNum,
}, page_count: count,
page_index: pageNum, user_status: true
page_count: count, });
user_status: true })
}); .then(() => {
}).then(function (value) { //console.log(value);
//console.log(value); })
}).catch(function (err) { .catch(() => {
//next(err); //next(err);
}) });
} else { } else {
res.redirect('/@/dashboard'); res.redirect('/@/dashboard');
} }
}); });
//-------------------------- //--------------------------
// BLOG POST ADD DISPLAY // BLOG POST ADD DISPLAY
//-------------------------- //--------------------------
router.get('/add/new', function (req, res) { router.get('/add/new', function(req, res) {
if (req.session.user) { if (req.session.user) {
res.render('dash/post-edit', { res.render('dash/post-edit', {
title: 'Make New Post', title: 'Make New Post',
mode: 'admin', mode: 'admin',
date: dateUtils.getDate('year', new Date()) + "-" + dateUtils.getDate('month', new Date()) + "-" + dateUtils.getDate('day', new Date()), date:
status: ['false', 'false', 'false'], dateUtils.getDate('year', new Date()) +
edit: false '-' +
}); dateUtils.getDate('month', new Date()) +
} else { '-' +
res.redirect('/@/dashboard'); dateUtils.getDate('day', new Date()),
} status: ['false', 'false', 'false'],
edit: false
});
} else {
res.redirect('/@/dashboard');
}
}); });
//-------------------------- //--------------------------
// BLOG POST EDIT DISPLAY // BLOG POST EDIT DISPLAY
//-------------------------- //--------------------------
router.get('/edit/:id', function (req, res) { router.get('/edit/:id', function(req, res) {
if (req.session.user) { if (req.session.user) {
Models.FreshPost.findOne({ Models.FreshPost.findOne({
where: { where: {
"post": { post: {
[Op.contains]: { [Op.contains]: {
uuid: req.params.id uuid: req.params.id
} }
} }
} }
}).then(item => { })
let featured = 'null'; .then(item => {
if (item.post.feature != null || item.post.feature != '') featured = item.post.feature.substr(8, item.post.feature.length); let featured = 'null';
let pretty = hljs.highlight('markdown', item.post.plaintext).value; if (item.post.feature != null || item.post.feature != '')
let sexydate = dateUtils.getDate('year', item.post.created) + "-" + dateUtils.getDate('month', item.post.created) + "-" + dateUtils.getDate('day', item.post.created) featured = item.post.feature.substr(8, item.post.feature.length);
res.render('dash/post-edit', { let pretty = hljs.highlight('markdown', item.post.plaintext).value;
id: item.id, let sexydate =
title: 'Edit Post', dateUtils.getDate('year', item.post.created) +
mode: 'admin', '-' +
post: item.post, dateUtils.getDate('month', item.post.created) +
date: sexydate, '-' +
colored: pretty, dateUtils.getDate('day', item.post.created);
html: item.post.plaintext, res.render('dash/post-edit', {
feature: featured, id: item.id,
status: [String(item.post.page), String(item.post.featured), String(item.post.published)], title: 'Edit Post',
edit: true mode: 'admin',
}); post: item.post,
}).then(function (value) { date: sexydate,
//console.log("VALUE: " + value); colored: pretty,
}).catch(function (err) { html: item.post.plaintext,
//console.log(err); feature: featured,
}) status: [
} else { String(item.post.page),
res.redirect('/@/dashboard'); String(item.post.featured),
} String(item.post.published)
],
edit: true
});
})
.then(() => {
//console.log("VALUE: " + value);
})
.catch(() => {
//console.log(err);
});
} else {
res.redirect('/@/dashboard');
}
}); });
module.exports = router; module.exports = router;

@ -2,77 +2,67 @@ const express = require('express');
const router = express.Router(); const router = express.Router();
const FileHound = require('filehound'); const FileHound = require('filehound');
const Models = require('../../models'); const Models = require('../../models');
const fs = require("fs-extra"); const fs = require('fs-extra');
var settings = []; var settings = [];
//-------------------------- //--------------------------
// SETTINGS // SETTINGS
//-------------------------- //--------------------------
router.get('/', function(req, res) router.get('/', function(req, res) {
{ fs.readJson('config/site-settings.json')
fs.readJson('config/site-settings.json').then(obj => .then(obj => {
{ settings = obj;
settings = obj; })
}).catch(err => .catch(() => {
{ //console.error(err)
//console.error(err) });
}) let themes = [];
let themes = []; FileHound.create()
FileHound.create().paths('themes').ext('json').find().then(files => .paths('themes')
{ .ext('json')
files.forEach(file => .find()
{ .then(files => {
fs.readJson(file).then(theme => files.forEach(file => {
{ fs.readJson(file)
if (theme.name == settings.theme) .then(theme => {
{ if (theme.name == settings.theme) {
themes.push( themes.push({
{ theme: theme,
theme: theme, current: 'true'
current: "true" });
}) } else {
} themes.push({
else theme: theme,
{ current: 'false'
themes.push( });
{ }
theme: theme, })
current: "false" .catch(() => {
}) //console.error(err)
} });
}).catch(err => });
{ if (req.session.user) {
//console.error(err) let memberInfo = [];
}) Models.User.findById(req.session.user.id).then(user => {
}); memberInfo.push({
if (req.session.user) handle: user.handle,
{ email: user.email,
let memberInfo = []; avi: user.avatar
Models.User.findById(req.session.user.id).then((user) => });
{ themes.sort(function(a, b) {
memberInfo.push( var textA = a.theme.name.toUpperCase();
{ var textB = b.theme.name.toUpperCase();
handle: user.handle, return textA < textB ? -1 : textA > textB ? 1 : 0;
email: user.email, });
avi: user.avatar res.render('dash/settings', {
}); title: 'Dashboard | Settings',
themes.sort(function(a, b) { themes: themes,
var textA = a.theme.name.toUpperCase(); settings: settings,
var textB = b.theme.name.toUpperCase(); member: memberInfo[0]
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0; });
}); });
res.render('dash/settings', } else {
{ res.redirect('/@/dashboard');
title: 'Dashboard | Settings', }
themes: themes, });
settings: settings,
member: memberInfo[0]
});
})
}
else
{
res.redirect('/@/dashboard');
}
});
}); });
module.exports = router; module.exports = router;

@ -5,92 +5,76 @@ const bCrypt = require('bcrypt-nodejs');
//-------------------------- //--------------------------
// Index // Index
//-------------------------- //--------------------------
router.get('/', function(req, res) router.get('/', function(req, res) {
{ var loggedIn = false;
var loggedIn = false if (req.session.user) loggedIn = true;
if (req.session.user) loggedIn = true; Models.FreshPost.findAll({
Models.FreshPost.findAll( order: [['id', 'DESC']]
{ })
order: [ .then(function(posts) {
['id', 'DESC'] let title = 'Fipamo Admin';
] let welcome = ''(!loggedIn)
}).then(function(posts) ? (welcome = 'Hello.')
{ : (welcome = 'Welcome back, ' + req.session.user.handle);
let title = 'Fipamo Admin'; let filtered = [];
(!loggedIn) ? welcome = "Hello." : welcome = "Welcome back, "+req.session.user.handle for (let index = 0; index < posts.length; index++) {
let filtered = []; let item = posts[index].post;
for (let index = 0; index < posts.length; index++) if (typeof item.deleted == 'undefined' || item.deleted == false) {
{ filtered.push(posts[index]);
let item = posts[index].post; } else {
if (typeof item.deleted == 'undefined' || item.deleted == false) continue;
{ }
filtered.push(posts[index]) }
} res.render('dash/index', {
else title: title,
{ welcome: welcome,
continue user_status: loggedIn,
} items: filtered
} });
res.render('dash/index', })
{ .then(() => {
title: title, //console.log(value);
welcome: welcome, })
user_status: loggedIn, .catch(() => {
items: filtered //next(err);
}); });
}).then(function(value)
{
//console.log(value);
}).catch(function(err)
{
//next(err);
})
}); });
//-------------------------- //--------------------------
// Login // Login
//-------------------------- //--------------------------
/* Handle Login POST */ /* Handle Login POST */
router.post('/login', function(req, res, next) router.post('/login', function(req, res) {
{ Models.User.findOne({
Models.User.findOne( where: {
{ handle: req.body.handle
where: }
{ })
handle: req.body.handle .then(user => {
} if (!isValidPassword(user, req.body.password)) {
}).then(user => return res.json({
{ message: 'CHECK YOUR PASSWORD'
if (!isValidPassword(user, req.body.password)) });
{ }
return res.json( let session = req.session;
{ session.user = user;
message: 'CHECK YOUR PASSWORD' res.redirect('/@/dashboard');
}); })
} .catch(() => {
let session = req.session; return res.json({
session.user = user; message: 'NOT FOUND, HAWS'
res.redirect('/@/dashboard'); });
}).catch(err => });
{
return res.json(
{
message: 'NOT FOUND, HAWS'
});
})
}); });
//-------------------------- //--------------------------
// Logout // Logout
//-------------------------- //--------------------------
router.post('/logout', function(req, res, next) router.post('/logout', function(req, res) {
{ req.logout();
req.logout(); return res.json({
return res.json( message: 'LOGGED OUT'
{ });
message: 'LOGGED OUT'
});
}); });
module.exports = router; module.exports = router;
var isValidPassword = function(user, password) var isValidPassword = function(user, password) {
{ return bCrypt.compareSync(password, user.password);
return bCrypt.compareSync(password, user.password); };
}

@ -1,23 +0,0 @@
import EventEmitter from '../events/EventEmitter';
class Animate extends EventEmitter {
//--------------------------
// constructor
//--------------------------
constructor() {
super();
}
//--------------------------
// methods
//--------------------------
object(properties) {
var animation = anime(
properties
);
//animation.start(properties);
}
//--------------------------
// event handlers
//--------------------------
}
export default Animate

@ -1,70 +0,0 @@
class TexEffects {
//--------------------------
// constructor
//--------------------------
constructor() {}
//--------------------------
// methods
//--------------------------
scramble(obj, offset, complete)
{
var scrambleText = new ScrambleText(obj, {
timeOffset: offset,
chars: [
'安',
'以',
'宇',
'衣',
'於',
'加',
'幾',
'久',
'計',
'己',
'左',
'之',
'寸',
'世',
'曽',
'太',
'知',
'川',
'天',
'止',
'奈',
'仁',
'奴',
'称',
'乃',
'波',
'比',
'不',
'部',
'保',
'末',
'美',
'武',
'女',
'毛',
'也',
'為',
'由',
'恵',
'与',
'良',
'利',
'留',
'礼',
'呂',
'和',
'遠',
'无'
],
callback: complete
}).start();
}
//--------------------------
// event handlers
//--------------------------
}
export default TexEffects

@ -3,17 +3,12 @@ export const EDITOR_UPLOAD_POST_IMAGE = 'editorUploadImage';
export const EDITOR_SAVE = 'editorSave'; export const EDITOR_SAVE = 'editorSave';
export const EDITOR_UPDATE = 'editorUpdate'; export const EDITOR_UPDATE = 'editorUpdate';
class EditorEvent class EditorEvent {
{ //--------------------------
// methods
//-------------------------- //--------------------------
// methods //--------------------------
//-------------------------- // event handlers
//--------------------------
//--------------------------
// event handlers
//--------------------------
} }
export default new EditorEvent export default new EditorEvent();

@ -1,57 +1,52 @@
class EventEmitter 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) {
// constructor var isFunction = function(obj) {
//-------------------------- return typeof obj == 'function' || false;
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 listeners = this.listeners.get(label),
var isFunction = function(obj) { index;
return typeof obj == 'function' || false;
};
var listeners = this.listeners.get(label), if (listeners && listeners.length) {
index; index = listeners.reduce((i, listener, index) => {
return isFunction(listener) && listener === callback ? (i = index) : i;
}, -1);
if (listeners && listeners.length) { if (index > -1) {
index = listeners.reduce((i, listener, index) => { listeners.splice(index, 1);
return (isFunction(listener) && listener === callback) this.listeners.set(label, listeners);
? i = index return true;
: i; }
}, -1); }
return false;
}
if (index > -1) { emitEvent(label, ...args) {
listeners.splice(index, 1); var listeners = this.listeners.get(label);
this.listeners.set(label, listeners); if (listeners && listeners.length) {
return true; listeners.forEach(listener => {
} listener(...args);
} });
return false; return true;
} }
return false;
emitEvent(label, ...args) { }
var listeners = this.listeners.get(label); //--------------------------
if (listeners && listeners.length) { // event handlers
listeners.forEach((listener) => { //--------------------------
listener(...args);
});
return true;
}
return false;
}
//--------------------------
// event handlers
//--------------------------
} }
export default EventEmitter export default EventEmitter;

@ -1,160 +1,156 @@
import * as DataEvent from '../events/DataEvent'; import * as DataEvent from '../events/DataEvent';
import DateUtils from '../utilities/DateUtils'; import DateUtils from '../utilities/DateUtils';
import { import { position } from 'caret-pos';
position,
offset
}
from 'caret-pos';
import EventEmitter from '../events/EventEmitter'; import EventEmitter from '../events/EventEmitter';
import * as EditorEvent from '../events/EditorEvent'; import * as EditorEvent from '../events/EditorEvent';
class TextEditor extends EventEmitter { class TextEditor extends EventEmitter {
/** /**
* Text Editor UI Component * Text Editor UI Component
* @constructor * @constructor
* @param {object} textEditor - Text area that will edit text * @param {object} textEditor - Text area that will edit text
* @param {number} scrollLimit - YPos where editor position will become fixed * @param {number} scrollLimit - YPos where editor position will become fixed
*/ */
//-------------------------- //--------------------------
// constructor // constructor
//-------------------------- //--------------------------
constructor(textEditor, scrollLimit) { constructor(textEditor, scrollLimit) {
super(); super();
hljs.initHighlightingOnLoad(); hljs.initHighlightingOnLoad();
this.dateUtils = new DateUtils(); this.dateUtils = new DateUtils();
this.textEditor = textEditor; this.textEditor = textEditor;
this.fixLimit = scrollLimit; this.fixLimit = scrollLimit;
this.caretPos = null; this.caretPos = null;
this.url = ''; this.url = '';
let self = this; this.setInputs();
this.setInputs(); window.addEventListener('scroll', () => {
window.addEventListener("scroll", f => { var fixLimit = this.fixLimit;
var fixLimit = this.fixLimit; if (window.pageYOffset >= fixLimit) {
if (window.pageYOffset >= fixLimit) { document.getElementById('edit-control').style.position = 'fixed';
document.getElementById('edit-control').style.position = "fixed" } else {
} else { document.getElementById('edit-control').style.position = 'relative';
document.getElementById('edit-control').style.position = "relative" }
} });
}); this.refresh();
this.refresh(); }
} //--------------------------
//-------------------------- // methods
// methods //--------------------------
//-------------------------- setInputs() {
setInputs() { let self = this;
let self = this; var editorButtons = document.querySelectorAll('.editor-button');
var editorButtons = document.querySelectorAll('.editor-button'); for (var i = 0, length = editorButtons.length; i < length; i++) {
for (var i = 0, length = editorButtons.length; i < length; i++) { editorButtons[i].addEventListener('click', e => this.handleEditorOption(e), false);
editorButtons[i].addEventListener('click', e => this.handleEditorOption(e), false); }
}
this.textEditor.addEventListener('input', e => {
let htmlTagRe = /<[a-z][\s\S]*>/g;
let text = this.textEditor.innerText;
if (e.inputType == "insertParagraph") return //cursor setting gets weird on return, so just back out
if (text.search(htmlTagRe) > -1) { this.textEditor.addEventListener('input', e => {
let caret = position(this.textEditor).pos; let htmlTagRe = /<[a-z][\s\S]*>/g;
self.refresh() let text = this.textEditor.innerText;
position(this.textEditor, caret); if (e.inputType == 'insertParagraph') return; //cursor setting gets weird on return, so just back out
}
})
}
refresh() {
var spiffed = hljs.highlight('markdown', this.textEditor.innerText).value;
spiffed = spiffed.replace(new RegExp('\r?\n', 'g'), '<br>');
var temp = document.createElement("div");
temp.innerText = spiffed;
this.textEditor.innerHTML = temp.innerText;
this.textEditor.style.maxWidth = '900px';
}
notify(type, data) {
switch (type) {
case DataEvent.POST_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(f => {
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.POST_ADDED:
// do nothing
break;
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE:
position(this.textEditor, this.caretPos);
var sel, range, pulled;
sel = window.getSelection(); //console.log(sel)
//console.log(note.message)
if (sel.rangeCount) {
range = sel.getRangeAt(0);
pulled = sel.getRangeAt(0).toString();
range.deleteContents();
range.insertNode(document.createTextNode("![image alt text](" + data + " 'image title')"));
}
this.refresh();
break;
}
} if (text.search(htmlTagRe) > -1) {
//-------------------------- let caret = position(this.textEditor).pos;
// event handlers self.refresh();
//-------------------------- position(this.textEditor, caret);
handleEditorOption(e) { }
e.preventDefault(); });
var self = this; }
var sel, range, pulled; refresh() {
sel = window.getSelection(); //console.log(sel) var spiffed = hljs.highlight('markdown', this.textEditor.innerText).value;
if (sel.rangeCount) { spiffed = spiffed.replace(new RegExp('\r?\n', 'g'), '<br>');
range = sel.getRangeAt(0); var temp = document.createElement('div');
pulled = sel.getRangeAt(0).toString(); temp.innerText = spiffed;
range.deleteContents(); this.textEditor.innerHTML = temp.innerText;
switch (e.target.id) { this.textEditor.style.maxWidth = '900px';
case "edit-bold": }
range.insertNode(document.createTextNode("**" + pulled + "**")); notify(type, data) {
break; switch (type) {
case "edit-italic": case DataEvent.POST_UPDATED:
range.insertNode(document.createTextNode("*" + pulled + "*")); document.getElementById('submit-update').classList.add('icon-hide');
break; document.getElementById('submit-good').classList.remove('icon-hide');
case "edit-strikethrough": document.getElementById('edit-update').classList.remove('submit-start');
range.insertNode(document.createTextNode("<del>" + pulled + "</del>")); document.getElementById('edit-update').classList.add('submit-cool');
break; setTimeout(() => {
case "edit-header1": document.getElementById('submit-update').classList.remove('icon-hide');
range.insertNode(document.createTextNode("# " + pulled)); document.getElementById('submit-good').classList.add('icon-hide');
break; document.getElementById('edit-update').classList.add('submit-start');
case "edit-header2": document.getElementById('edit-update').classList.remove('submit-cool');
range.insertNode(document.createTextNode("## " + pulled)); }, 2000);
break; break;
case "edit-header3": case DataEvent.POST_ADDED:
range.insertNode(document.createTextNode("### " + pulled)); // do nothing
break; break;
case "edit-image": case EditorEvent.EDITOR_UPLOAD_POST_IMAGE:
this.caretPos = position(this.textEditor).pos; position(this.textEditor, this.caretPos);
this.emitEvent(EditorEvent.EDITOR_UPLOAD_POST_IMAGE); var sel, range;
break; //var pulled;
case "submit-save": sel = window.getSelection(); //console.log(sel)
case "edit-save": //console.log(note.message)
this.emitEvent(EditorEvent.EDITOR_SAVE); if (sel.rangeCount) {
break; range = sel.getRangeAt(0);
case "submit-update": //pulled = sel.getRangeAt(0).toString();
case "edit-update": range.deleteContents();
this.emitEvent(EditorEvent.EDITOR_UPDATE); range.insertNode(
break document.createTextNode('![image alt text](' + data + " 'image title')")
case "edit-link": );
range.insertNode(document.createTextNode("[" + pulled + "](PASTE URL HERE)")); }
break; this.refresh();
case "edit-delete": break;
this.emitEvent(EditorEvent.EDITOR_DELETE); }
break }
default: //--------------------------
//range.insertNode(document.createTextNode("[" + self.url + "](PASTE URL HERE)")); // event handlers
break; //--------------------------
} handleEditorOption(e) {
} e.preventDefault();
this.refresh() var sel, range, pulled;
} sel = window.getSelection(); //console.log(sel)
if (sel.rangeCount) {
range = sel.getRangeAt(0);
pulled = sel.getRangeAt(0).toString();
range.deleteContents();
switch (e.target.id) {
case 'edit-bold':
range.insertNode(document.createTextNode('**' + pulled + '**'));
break;
case 'edit-italic':
range.insertNode(document.createTextNode('*' + pulled + '*'));
break;
case 'edit-strikethrough':
range.insertNode(document.createTextNode('<del>' + pulled + '</del>'));
break;
case 'edit-header1':
range.insertNode(document.createTextNode('# ' + pulled));
break;
case 'edit-header2':
range.insertNode(document.createTextNode('## ' + pulled));
break;
case 'edit-header3':
range.insertNode(document.createTextNode('### ' + pulled));
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-link':
range.insertNode(document.createTextNode('[' + pulled + '](PASTE URL HERE)'));
break;
case 'edit-delete':
this.emitEvent(EditorEvent.EDITOR_DELETE);
break;
default:
//range.insertNode(document.createTextNode("[" + self.url + "](PASTE URL HERE)"));
break;
}
}
this.refresh();
}
} }
export default TextEditor export default TextEditor;

@ -1,204 +1,177 @@
"use strict"; 'use strict';
import DataUtils, import DataUtils, { REQUEST_TYPE_POST, CONTENT_TYPE_JSON } from '../utilities/DataUtils';
{
REQUEST_TYPE_GET,
REQUEST_TYPE_PUT,
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
}
from '../utilities/DataUtils';
import Dexie from 'dexie'; import Dexie from 'dexie';
import * as DataEvent from '../events/DataEvent'; import * as DataEvent from '../events/DataEvent';
export var COUNT; export var COUNT;
export var FINAL_KEY; export var FINAL_KEY;
export default class DBUtils export default class DBUtils {
{ //--------------------------
//-------------------------- // constructor
// constructor //--------------------------
//-------------------------- constructor() {
constructor() /**
{ * NOTE: DB ERRORS REPLICATE.
/** * WHEN FIXING A BUG, FIX DATA WITH JSON BACKUP
* NOTE: DB ERRORS REPLICATE. */
* WHEN FIXING A BUG, FIX DATA WITH JSON BACKUP this.dataUtils = new DataUtils();
*/ this.db = new Dexie('fipamo_posts');
this.dataUtils = new DataUtils(); this.db.version(1).stores({
this.db = new Dexie("fipamo_posts"); postList: 'id,post'
this.db.version(1).stores( });
{ this.db.postList.toArray(array => {
postList: 'id,post' COUNT = array.length;
}); FINAL_KEY = array[COUNT - 1].id;
this.db.postList.toArray(array => });
{ }
COUNT = array.length; //--------------------------
FINAL_KEY = array[COUNT - 1].id; // methods
}) //--------------------------
} modify(id, postData) {
//-------------------------- let self = this;
// methods let freshID;
//-------------------------- return new Promise(function(resolve, reject) {
modify(id, postData) if (id == null) {
{ self.db.postList
let self = this; .put(postData)
let freshID; .then(fresh => {
return new Promise(function(resolve, reject) freshID = fresh;
{ })
if (id == null) .catch(e => {
{ let err = {
self.db.postList.put(postData).then(fresh => message: 'PUT ERROR',
{ error: e
freshID = fresh; };
}).catch(e =>
{ return err;
let err = { });
message: "PUT ERROR", } else {
error: e //console.log("UPDATED", postData);
} self.db.postList
}); .update(Number(id), {
} post: postData
else })
{ .then(() => {})
//console.log("UPDATED", postData); .catch(e => {
self.db.postList.update(Number(id), let err = {
{ message: 'UPDATE ERROR',
post: postData error: e
}).then(updated => };
{}).catch(e => return err;
{ });
let err = { }
message: "UPDATE ERROR", self.db.postList.toArray(array => {
error: e self.syncRemote(array, freshID)
} .then(response => {
}); resolve({
} response
self.db.postList.toArray(array => });
{ })
self.syncRemote(array, freshID).then(response => .catch(err => {
{ reject({
resolve( err
{ });
response });
}) });
}).catch(err => });
{ }
reject( syncLocal(array) {
{ let self = this;
err return new Promise(function(resolve, reject) {
}); self.db.postList.clear().then(() => {
}); self.db.postList
}) .bulkAdd(array)
}) .then(() => {
} self.db.postList.toArray(() => {
syncLocal(array) let event = DataEvent.LOCAL_DB_READY;
{ resolve({
let self = this; event
return new Promise(function(resolve, reject) });
{ });
self.db.postList.clear().then(result => })
{ .catch(Dexie.BulkError, e => {
self.db.postList.bulkAdd(array).then(key => reject({
{ e
self.db.postList.toArray(array => });
{ });
let event = DataEvent.LOCAL_DB_READY });
resolve( });
{ }
event syncRemote(db, newPostId) {
}) let self = this;
}) return new Promise(function(resolve, reject) {
}).catch(Dexie.BulkError, e => self.dataUtils
{ .request(
reject( '/api/post/sync',
{ DataEvent.POSTS_SYNCED,
e REQUEST_TYPE_POST,
}) CONTENT_TYPE_JSON,
}) db
}) )
}) .then(response => {
} let bounce = {
syncRemote(db, newPostId) message: response,
{ newPost: newPostId
let self = this; };
return new Promise(function(resolve, reject) resolve(bounce);
{ })
self.dataUtils.request('/api/post/sync', DataEvent.POSTS_SYNCED, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, db).then((response) => .catch(err => {
{ reject(err);
let bounce = { });
message: response, });
newPost: newPostId }
} getPost(id) {
resolve(bounce) let self = this;
}).catch((err) => if (id == null) {
{ return new Promise(function(resolve, reject) {
reject(err); self.db.postList
}) .toArray(array => {
}) resolve(array);
} })
getPost(id) .catch(err => {
{ reject(err);
let self = this; });
if (id == null) });
{ } else {
return new Promise(function(resolve, reject) return new Promise(function(resolve, reject) {
{ self.db.postList
self.db.postList.toArray(array => .get(Number(id))
{ .then(obj => {
resolve(array) resolve(obj);
}).catch(err => })
{ .catch(err => {
reject(err) reject(err);
}) });
}) });
} }
else }
{ archivePost(id, archive) {
return new Promise(function(resolve, reject) let self = this;
{ return new Promise(function(resolve, reject) {
self.db.postList.get(Number(id)).then(obj => self.db.postList
{ .update(Number(id), {
resolve(obj) post: archive
}).catch(err => })
{ .then(() => {
reject(err) self.db.postList.toArray(array => {
}) self.syncRemote(array, null)
}) .then(response => {
} resolve({
} response
archivePost(id, archive) });
{ })
let self = this; .catch(err => {
return new Promise(function(resolve, reject) reject({
{ err
self.db.postList.update(Number(id), });
{ });
post: archive });
}).then(deleted => })
{ .catch(() => {
self.db.postList.toArray(array => //console.log('ERROR', e);
{ });
self.syncRemote(array, null).then(response => });
{ }
resolve( //--------------------------
{ // event handlers
response //--------------------------
}) }
}).catch(err =>
{
reject(
{
err
});
});
})
}).catch(e =>
{
console.log("ERROR", e)
});
})
}
//--------------------------
// event handlers
//--------------------------
}

@ -1,31 +1,27 @@
class DOMUtils class DOMUtils {
{ //--------------------------
// constructor
//--------------------------
constructor() {}
//--------------------------
// methods
//--------------------------
getWindowXY() {
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight || e.clientHeight || g.clientHeight;
//-------------------------- var dimensions = {
// constructor windowHeight: y,
//-------------------------- windowWidth: x
constructor() };
{} return dimensions;
//-------------------------- }
// methods //--------------------------
//-------------------------- // event handlers
getWindowXY() //--------------------------
{
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight || e.clientHeight || g.clientHeight;
var dimensions = {
windowHeight: y,
windowWidth: x
}
return dimensions;
}
//--------------------------
// event handlers
//--------------------------
} }
export default DOMUtils export default DOMUtils;

@ -1,139 +1,123 @@
export const REQUEST_TYPE_POST = "POST"; export const REQUEST_TYPE_POST = 'POST';
export const REQUEST_TYPE_GET = "GET"; export const REQUEST_TYPE_GET = 'GET';
export const REQUEST_TYPE_PUT = "PUT"; export const REQUEST_TYPE_PUT = 'PUT';
export const REQUEST_TYPE_DELETE = "DELETE"; export const REQUEST_TYPE_DELETE = 'DELETE';
export const CONTENT_TYPE_JSON = 'json'; export const CONTENT_TYPE_JSON = 'json';
export const CONTENT_TYPE_FORM = 'x-www-form-urlencoded'; export const CONTENT_TYPE_FORM = 'x-www-form-urlencoded';
import EventEmitter from '../events/EventEmitter'; import EventEmitter from '../events/EventEmitter';
import * as DataEvent from '../events/DataEvent'; class DataUtils extends EventEmitter {
class DataUtils extends EventEmitter //--------------------------
{ // constructor
//-------------------------- //--------------------------
// constructor constructor() {
//-------------------------- super();
constructor() }
{ //--------------------------
super(); // methods
var self = this; //--------------------------
} request(
//-------------------------- requestURL,
// methods eventType,
//-------------------------- requestType = REQUEST_TYPE_GET,
request(requestURL, eventType, requestType = REQUEST_TYPE_GET, contentType = CONTENT_TYPE_JSON, requestData = null) contentType = CONTENT_TYPE_JSON,
{ requestData = null
var self = this; ) {
return new Promise(function(resolve, reject) var self = this;
{ return new Promise(function(resolve, reject) {
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
request.upload.onprogress = self.handleLoadProgress; request.upload.onprogress = self.handleLoadProgress;
request.open(requestType, requestURL, true); request.open(requestType, requestURL, true);
request.onload = function(e) request.onload = () => {
{ if (request.status == 200) {
if (request.status == 200) resolve({
{ request,
resolve( eventType
{ });
request, } else {
eventType reject({
}); request,
} eventType
else });
{ }
reject( };
{ if (requestType == REQUEST_TYPE_PUT || requestType == REQUEST_TYPE_POST) {
request, switch (contentType) {
eventType case CONTENT_TYPE_JSON:
}); request.setRequestHeader('Content-type', 'application/' + contentType);
}; request.send(JSON.stringify(requestData));
}; break;
if (requestType == REQUEST_TYPE_PUT || requestType == REQUEST_TYPE_POST) case CONTENT_TYPE_FORM:
{ request.send(requestData);
switch (contentType) break;
{ }
case CONTENT_TYPE_JSON: } else {
request.setRequestHeader("Content-type", "application/" + contentType); request.send();
request.send(JSON.stringify(requestData)); }
break; });
case CONTENT_TYPE_FORM: }
request.send(requestData); imgLoad(url) {
break; 'use strict';
} // Create new promise with the Promise() constructor;
} // This has as its argument a function with two parameters, resolve and reject
else return new Promise(function(resolve, reject) {
{ // Standard XHR to load an image
request.send(); var request = new XMLHttpRequest();
} request.open('GET', url);
}) request.responseType = 'blob';
} // When the request loads, check whether it was successful
imgLoad(url) request.onload = function() {
{ if (request.status === 200) {
'use strict'; // If successful, resolve the promise by passing back the request response
// Create new promise with the Promise() constructor; resolve(request.response);
// This has as its argument a function with two parameters, resolve and reject } else {
return new Promise(function(resolve, reject) // If it fails, reject the promise with a error message
{ reject(
// Standard XHR to load an image new Error(
var request = new XMLHttpRequest(); "Image didn't load successfully; error code:" + request.statusText
request.open('GET', url); )
request.responseType = 'blob'; );
// When the request loads, check whether it was successful }
request.onload = function() };
{ request.onerror = function() {
if (request.status === 200) // 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
// If successful, resolve the promise by passing back the request response reject(new Error('There was a network error.'));
resolve(request.response); };
} // Send the request
else request.send();
{ });
// If it fails, reject the promise with a error message }
reject(new Error('Image didn\'t load successfully; error code:' + request.statusText)); loadImage(src) {
} 'use strict';
}; let self = this;
request.onerror = function() return new Promise(function(resolve, reject) {
{ // Get a reference to the body element, and create a new image object
// Also deal with the case when the entire request fails to begin with var myImage = new Image();
// This is probably a network error, so reject the promise with an appropriate message myImage.crossOrigin = ''; // or "anonymous"
reject(new Error('There was a network error.')); // 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
// Send the request self.imgLoad(src).then(
request.send(); function(response) {
}); // The first runs when the promise resolves, with the request.reponse specified within the resolve() method.
} var imageURL = window.URL.createObjectURL(response);
loadImage(src) resolve(imageURL);
{ //$('background-content').setStyle('background-image', 'url('+imageURL+')') //myImage.src = imageURL;
'use strict'; //console.log(imageURL);
let self = this; //body.appendChild(myImage);
return new Promise(function(resolve, reject) // The second runs when the promise is rejected, and logs the Error specified with the reject() method.
{ },
// Get a reference to the body element, and create a new image object function(Error) {
var body = document.querySelector('body'), reject(Error);
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) //--------------------------
{ // event handlers
// The first runs when the promise resolves, with the request.reponse specified within the resolve() method. //--------------------------
var imageURL = window.URL.createObjectURL(response); handleLoadProgress() {
resolve(imageURL); //var percentComplete = Math.ceil((e.loaded / e.total) * 100);
//$('background-content').setStyle('background-image', 'url('+imageURL+')') //myImage.src = imageURL; //console.log(percentComplete);
//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)
});
});
}
//--------------------------
// event handlers
//--------------------------
handleLoadProgress(e)
{
var percentComplete = Math.ceil((e.loaded / e.total) * 100);
//console.log(percentComplete);
}
} }
export default DataUtils; export default DataUtils;

@ -1,61 +1,102 @@
class DateUtils { class DateUtils {
//--------------------------
// constructor
//--------------------------
constructor() {}
//-------------------------- //--------------------------
// constructor // methods
//-------------------------- //--------------------------
constructor() {} getMKtime() {
var time =
new Date(
new Date().getFullYear(),
new Date().getMonth(),
new Date().getDate(),
new Date().getHours(),
new Date().getMinutes(),
new Date().getSeconds(),
0
).getTime() / 1000;
return time;
}
//-------------------------- convertMKtime(seconds) {
// methods var date = new Date(seconds * 1000);
//-------------------------- return date;
getMKtime() { }
var time = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), new Date().getHours(), new Date().getMinutes(), new Date().getSeconds(), 0).getTime() / 1000;
return time;
}
convertMKtime(seconds) { getDate(type, rawdate) {
var date = new Date(seconds * 1000); var day =
return date; rawdate != null || rawdate != ''
} ? String(new Date(rawdate).getUTCDate())
: String(new Date().getUTCDate());
var month =
rawdate != null || rawdate != ''
? String(new Date(rawdate).getUTCMonth() + 1)
: String(new Date().getUTCMonth() + 1);
var year =
rawdate != null || rawdate != ''
? String(new Date(rawdate).getUTCFullYear())
: String(new Date().getUTCFullYear());
var hour =
rawdate != null || rawdate != ''
? String(new Date(rawdate).getUTCHours())
: String(new Date().getUTCHours());
var minute =
rawdate != null || rawdate != ''
? String(new Date(rawdate).getUTCMinutes())
: String(new Date().getUTCMinutes());
var seconds =
rawdate != null || rawdate != ''
? String(new Date(rawdate).getUTCSeconds())
: String(new Date().getUTCSeconds());
var millisecond =
rawdate != null || rawdate != ''
? String(new Date(rawdate).getUTCMilliseconds())
: String(new Date().getUTCMilliseconds());
var offset =
rawdate != null || rawdate != ''
? String(new Date(rawdate).getTimezoneOffset())
: String(new Date().getTimezoneOffset());
if (day.length == 1) day = String('0' + day);
if (month.length == 1) month = String('0' + month);
offset = String(offset / 60);
if (offset.length == 1) offset = String('0' + offset);
switch (type) {
case 'day':
return day;
getDate(type, rawdate) { case 'month':
var day = ((rawdate != null || rawdate != '') ? String(new Date(rawdate).getUTCDate()) : String(new Date().getUTCDate())); return month;
var month = ((rawdate != null || rawdate != '') ? String(new Date(rawdate).getUTCMonth() + 1) : String(new Date().getUTCMonth() + 1)); case 'year':
var year = ((rawdate != null || rawdate != '') ? String(new Date(rawdate).getUTCFullYear()) : String(new Date().getUTCFullYear())); return year;
var hour = ((rawdate != null || rawdate != '') ? String(new Date(rawdate).getUTCHours()) : String(new Date().getUTCHours())); case 'stamp':
var minute = ((rawdate != null || rawdate != '') ? String(new Date(rawdate).getUTCMinutes()) : String(new Date().getUTCMinutes())); return String(
var seconds = ((rawdate != null || rawdate != '') ? String(new Date(rawdate).getUTCSeconds()) : String(new Date().getUTCSeconds())); year +
var millisecond = ((rawdate != null || rawdate != '') ? String(new Date(rawdate).getUTCMilliseconds()) : String(new Date().getUTCMilliseconds())); '-' +
var offset = ((rawdate != null || rawdate != '') ? String(new Date(rawdate).getTimezoneOffset()) : String(new Date().getTimezoneOffset())); month +
if (day.length == 1) '-' +
day = String("0" + day); day +
if (month.length == 1) ' ' +
month = String("0" + month); hour +
offset = String(offset / 60); ':' +
if (offset.length == 1) minute +
offset = String("0" + offset); ':' +
switch (type) { seconds +
case "day": '.' +
return day; millisecond +
break; '-' +
case "month": offset
return month; );
break; default:
case "year": return String(year + '-' + month + '-' + day);
return year; }
break; }
case "stamp":
return String(year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + seconds + "." + millisecond + "-" + (offset));
break
default:
return String(year + "-" + month + "-" + day);
break;
}
}
//-------------------------- //--------------------------
// event handlers // event handlers
//-------------------------- //--------------------------
} }
export default DateUtils export default DateUtils;

@ -1,162 +1,137 @@
export const roles = { export const roles = {
hnic: hnic: {
{ client_admin: {
"client_admin": create: true,
{ read: true,
"create": true, update: true,
"read": true, delete: true
"update": true, },
"delete": true client_user: {
}, create: true,
"client_user": read: true,
{ update: true,
"create": true, delete: true
"read": true, },
"update": true, client_project: {
"delete": true create: true,
}, read: true,
"client_project": update: true,
{ delete: true
"create": true, },
"read": true, folio_project: {
"update": true, create: true,
"delete": true read: true,
}, update: true,
"folio_project": delete: true
{ },
"create": true, bookmark: {
"read": true, create: true,
"update": true, read: true,
"delete": true update: true,
}, delete: true
"bookmark": },
{ post: {
"create": true, create: true,
"read": true, read: true,
"update": true, update: true,
"delete": true delete: true
}, },
"post": settings: {
{ create: true,
"create": true, read: true,
"read": true, update: true,
"update": true, delete: true
"delete": true }
}, },
"settings": client: {
{ client_admin: {
"create": true, create: false,
"read": true, read: true,
"update": true, update: false,
"delete": true delete: false
} },
}, client_user: {
client: create: true,
{ read: true,
"client_admin": update: true,
{ delete: true
"create": false, },
"read": true, client_project: {
"update": false, create: true,
"delete": false read: true,
}, update: true,
"client_user": delete: false
{ },
"create": true, folio_project: {
"read": true, create: false,
"update": true, read: false,
"delete": true update: false,
}, delete: false
"client_project": }
{ },
"create": true, user: {
"read": true, client_admin: {
"update": true, create: false,
"delete": false read: false,
}, update: false,
"folio_project": delete: false
{ },
"create": false, client_user: {
"read": false, create: false,
"update": false, read: true,
"delete": false update: false,
} delete: false
}, },
user: client_project: {
{ create: false,
"client_admin": read: true,
{ update: true,
"create": false, delete: false
"read": false, },
"update": false, folio_project: {
"delete": false create: false,
}, read: false,
"client_user": update: false,
{ delete: false
"create": false, },
"read": true, bookmark: {
"update": false, create: true,
"delete": false read: true,
}, update: true,
"client_project": delete: true
{ },
"create": false, post: {
"read": true, create: false,
"update": true, read: false,
"delete": false update: false,
}, delete: false
"folio_project": }
{ }
"create": false,
"read": false,
"update": false,
"delete": false
},
"bookmark":
{
"create": true,
"read": true,
"update": true,
"delete": true
},
"post":
{
"create": false,
"read": false,
"update": false,
"delete": false
}
}
}; };
export const TASK_CREATE = 'create' export const TASK_CREATE = 'create';
export const TASK_UPDATE = 'update' export const TASK_UPDATE = 'update';
export const TASK_READ = 'read' export const TASK_READ = 'read';
export const TASK_DELETE = 'delete' export const TASK_DELETE = 'delete';
export const OBJECT_CLIENT_ADMIN = 'client_admin' export const OBJECT_CLIENT_ADMIN = 'client_admin';
export const OBJECT_CLIENT_USER = 'client_user' export const OBJECT_CLIENT_USER = 'client_user';
export const OBJECT_PROJECT_CLIENT = 'client_project' export const OBJECT_PROJECT_CLIENT = 'client_project';
export const OBJECT_PROJECT_FOLIO = 'folio_project' export const OBJECT_PROJECT_FOLIO = 'folio_project';
export const OBJECT_BOOKMARK = 'bookmark' export const OBJECT_BOOKMARK = 'bookmark';
export const OBJECT_POST = 'post' export const OBJECT_POST = 'post';
export const OBJECT_SETTINGS = 'settings' export const OBJECT_SETTINGS = 'settings';
export default class RightsManager export default class RightsManager {
{ //--------------------------
//-------------------------- // constructor
// constructor //--------------------------
//-------------------------- constructor() {}
constructor() //--------------------------
{ // methods
var self = this; //--------------------------
} check(role, object, task) {
//-------------------------- //console.log(role + " *** " + object + " *** " + task);
// methods return roles[role][object][task];
//-------------------------- }
check(role, object, task) //--------------------------
{ // event handlers
//console.log(role + " *** " + object + " *** " + task); //--------------------------
return roles[role][object][task]; }
}
//--------------------------
// event handlers
//--------------------------
}

@ -1,65 +1,68 @@
class StringUtils 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) {
// constructor var optTemp = 0,
//-------------------------- i = 0,
constructor() noquotes = false;
{} if (typeof quote_style === 'undefined') {
//-------------------------- quote_style = 2;
// methods }
//-------------------------- string = string
cleanString(string) .toString()
{ .replace(/&lt;/g, '<')
var clean = string.replace(/(^\-+|[^a-zA-Z0-9\/_| -]+|\-+$)/g, '').toLowerCase().replace(/[\/_| -]+/g, '-'); .replace(/&gt;/g, '>');
return clean; 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(/&#0*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
// string = string.replace(/&apos;|&#x0*27;/g, "'"); // This would also be useful here, but not a part of PHP
}
if (!noquotes) {
string = string.replace(/&quot;/g, '"');
}
// Put this in last place to avoid escape being double-decoded
string = string.replace(/&amp;/g, '&');
return string;
}
decodeHTML(string, quote_style) { //--------------------------
var optTemp = 0, // event handlers
i = 0, //--------------------------
noquotes = false;
if (typeof quote_style === 'undefined') {
quote_style = 2;
}
string = string.toString().replace(/&lt;/g, '<').replace(/&gt;/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(/&#0*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
// string = string.replace(/&apos;|&#x0*27;/g, "'"); // This would also be useful here, but not a part of PHP
}
if (!noquotes) {
string = string.replace(/&quot;/g, '"');
}
// Put this in last place to avoid escape being double-decoded
string = string.replace(/&amp;/g, '&');
return string;
}
//--------------------------
// event handlers
//--------------------------
} }
export default StringUtils export default StringUtils;

@ -5,7 +5,7 @@
*/ */
var app = require('./brain/app'); var app = require('./brain/app');
var debug = require('debug')('thetwelfthhouse:server'); var debug = require('debug')('fipamo:server');
var http = require('http'); var http = require('http');
var models = require('./brain/models'); var models = require('./brain/models');
@ -30,37 +30,35 @@ server.listen(port);
server.on('error', onError); server.on('error', onError);
server.on('listening', onListening); server.on('listening', onListening);
models.sequelize.sync().then(function() { models.sequelize.sync().then(function() {
/** /**
* Listen on provided port, on all network interfaces. * Listen on provided port, on all network interfaces.
*/ */
server.listen(port, function() { server.listen(port, function() {
debug('Express server listening on port ' + server.address().port); debug('Express server listening on port ' + server.address().port);
}); });
server.on('error', onError); server.on('error', onError);
server.on('listening', onListening); server.on('listening', onListening);
}); });
/** /**
* Normalize a port into a number, string, or false. * Normalize a port into a number, string, or false.
*/ */
function normalizePort(val) { function normalizePort(val) {
var port = parseInt(val, 10); var port = parseInt(val, 10);
if (isNaN(port)) { if (isNaN(port)) {
// named pipe // named pipe
return val; return val;
} }
if (port >= 0) { if (port >= 0) {
// port number // port number
return port; return port;
} }
return false; return false;
} }
/** /**
@ -68,27 +66,25 @@ function normalizePort(val) {
*/ */
function onError(error) { function onError(error) {
if (error.syscall !== 'listen') { if (error.syscall !== 'listen') {
throw error; throw error;
} }
var bind = typeof port === 'string' ? var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
'Pipe ' + port :
'Port ' + port // handle specific listen errors with friendly messages
switch (error.code) {
// handle specific listen errors with friendly messages case 'EACCES':
switch (error.code) { console.error(bind + ' requires elevated privileges');
case 'EACCES': process.exit(1);
console.error(bind + ' requires elevated privileges'); break;
process.exit(1); case 'EADDRINUSE':
break; console.error(bind + ' is already in use');
case 'EADDRINUSE': process.exit(1);
console.error(bind + ' is already in use'); break;
process.exit(1); default:
break; throw error;
default: }
throw error;
}
} }
/** /**
@ -96,9 +92,7 @@ function onError(error) {
*/ */
function onListening() { function onListening() {
var addr = server.address(); var addr = server.address();
var bind = typeof addr === 'string' ? var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
'pipe ' + addr : debug('Listening on ' + bind);
'port ' + addr.port;
debug('Listening on ' + bind);
} }

@ -1,41 +1,39 @@
import DataUtils, import DataUtils, {
{ REQUEST_TYPE_POST,
REQUEST_TYPE_GET, CONTENT_TYPE_JSON
REQUEST_TYPE_PUT, } from '../../../../../brain//tools/utilities/DataUtils';
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
}
from '../../../../../brain//tools/utilities/DataUtils';
import * as DataEvent from '../../../../../brain/tools/events/DataEvent'; import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
export default class Mailer export default class Mailer {
{ //--------------------------
//-------------------------- // constructor
// constructor //--------------------------
//-------------------------- constructor() {
constructor() this.dataUtils = new DataUtils();
{ }
this.dataUtils = new DataUtils(); //--------------------------
} // methods
//-------------------------- //--------------------------
// methods sendMail() {
//-------------------------- var self = this;
sendMail() let mailData = {
{ content: 'This is a test email'
var self = this; };
let mailData = { self.dataUtils
content: "This is a test email" .request(
} '/api/mail',
self.dataUtils.request('/api/mail', DataEvent.SETTINGS_UPDATED, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, mailData).then((response) => DataEvent.SETTINGS_UPDATED,
{ REQUEST_TYPE_POST,
console.log(response) CONTENT_TYPE_JSON,
}).catch((err) => mailData
{ )
console.log(err) .then(() => {
}) //console.log(response);
} })
//-------------------------- .catch(() => {
// event handlers //console.log(err);
//-------------------------- });
} }
//--------------------------
// event handlers
//--------------------------
}

@ -1,71 +1,62 @@
import DataUtils, import DataUtils, {
{ REQUEST_TYPE_POST,
REQUEST_TYPE_GET, CONTENT_TYPE_JSON
REQUEST_TYPE_PUT, } from '../../../../../brain//tools/utilities/DataUtils';
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
}
from '../../../../../brain//tools/utilities/DataUtils';
import StringUtils from '../../../../../brain//tools/utilities/StringUtils';
import DateUtils from '../../../../../brain/tools/utilities/DateUtils'; import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
import * as DataEvent from '../../../../../brain/tools/events/DataEvent'; import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
import DBUtils from '../../../../../brain/tools/utilities/DBUtils'; import DBUtils from '../../../../../brain/tools/utilities/DBUtils';
export default class NavActions export default class NavActions {
{ //--------------------------
//-------------------------- // constructor
// constructor //--------------------------
//-------------------------- constructor() {
constructor() this.dataUtils = new DataUtils();
{ this.dateUtils = new DateUtils();
this.dataUtils = new DataUtils(); this.dbutils = new DBUtils();
this.dateUtils = new DateUtils(); }
this.dbutils = new DBUtils(); //--------------------------
} // methods
//-------------------------- //--------------------------
// methods save() {
//-------------------------- let self = this;
save() let navData = [];
{ let items = document.getElementById('nav-pages').children;
let self = this; for (let index = 0; index < items.length; index++) {
let navData = []; navData.push({
let items = document.getElementById('nav-pages').children; title: items[index].getElementsByTagName('label')[0].innerHTML,
for (let index = 0; index < items.length; index++) id: items[index].id,
{ slug: items[index].getAttribute('data-slug'),
navData.push( uuid: items[index].getAttribute('data-uuid')
{ });
title: items[index].getElementsByTagName('label')[0].innerHTML, }
id: items[index].id, return new Promise(function(resolve, reject) {
slug: items[index].getAttribute('data-slug'), self.dataUtils
uuid: items[index].getAttribute('data-uuid') .request(
}) '/api/settings/nav-sync',
} DataEvent.SETTINGS_UPDATED,
return new Promise(function(resolve, reject) REQUEST_TYPE_POST,
{ CONTENT_TYPE_JSON,
self.dataUtils.request('/api/settings/nav-sync', DataEvent.SETTINGS_UPDATED, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, navData).then((response) => navData
{ )
resolve(response) .then(response => {
}).catch((err) => resolve(response);
{ })
reject(err); .catch(err => {
}) reject(err);
}) });
} });
removeItem(id) }
{ removeItem(id) {
let self = this; let self = this;
this.dbutils.getPost(id).then(post => this.dbutils.getPost(id).then(post => {
{ post.post.page = 'false';
post.post.page = "false"; self.dbutils.modify(id, post.post).then(() => {
self.dbutils.modify(id, post.post).then(r => document.getElementById('nav-pages').removeChild(document.getElementById(id));
{ self.save();
document.getElementById('nav-pages').removeChild(document.getElementById(id)); });
self.save() });
}) }
}) //--------------------------
} // event handlers
//-------------------------- //--------------------------
// event handlers }
//--------------------------
}

@ -1,162 +1,155 @@
import DataUtils, import DataUtils, {
{ REQUEST_TYPE_POST,
REQUEST_TYPE_GET, CONTENT_TYPE_JSON
REQUEST_TYPE_PUT, } from '../../../../../brain//tools/utilities/DataUtils';
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
}
from '../../../../../brain//tools/utilities/DataUtils';
import StringUtils from '../../../../../brain//tools/utilities/StringUtils'; import StringUtils from '../../../../../brain//tools/utilities/StringUtils';
import DateUtils from '../../../../../brain/tools/utilities/DateUtils'; import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
import DBUtils from '../../../../../brain/tools/utilities/DBUtils'; import DBUtils from '../../../../../brain/tools/utilities/DBUtils';
var uuidv4 = require('uuid/v4'); var uuidv4 = require('uuid/v4');
import * as DataEvent from '../../../../../brain/tools/events/DataEvent'; import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
export default class PostActions export default class PostActions {
{ //--------------------------
//-------------------------- // constructor
// constructor //--------------------------
//-------------------------- constructor() {
constructor() this.dataUtils = new DataUtils();
{ this.dateUtils = new DateUtils();
this.dataUtils = new DataUtils(); this.dbUtils = new DBUtils();
this.dateUtils = new DateUtils(); }
this.dbUtils = new DBUtils(); //--------------------------
} // methods
//-------------------------- //--------------------------
// methods update(id, data, files, lastKey) {
//-------------------------- let self = this;
update(id, data, files, lastKey) let freshData;
{ return new Promise(function(resolve, reject) {
let self = this; let txt = document.createElement('textarea');
let freshData; txt.innerHTML = document.getElementById('edit-post-text').innerHTML;
return new Promise(function(resolve, reject) let html = txt.value;
{ html = html.replace(/<\/?span[^>]*>/g, ''); //removes highightjs styling
let txt = document.createElement("textarea"); html = html.replace(/<\/?br[^>]*>/g, '\n'); //convert back to encoded line break for storage
txt.innerHTML = document.getElementById('edit-post-text').innerHTML; data.title = document.getElementById('post_title').value;
let html = txt.value; data.slug = new StringUtils().cleanString(document.getElementById('post_title').value);
html = html.replace(/<\/?span[^>]*>/g, ""); //removes highightjs styling data.plaintext = html;
html = html.replace(/<\/?br[^>]*>/g, "\n"); //convert back to encoded line break for storage data.html = html;
data.title = document.getElementById('post_title').value; data.created = document.getElementById('post-date').value;
data.slug = new StringUtils().cleanString(document.getElementById('post_title').value) data.tags = document.getElementById('post_tags').value;
data.plaintext = html; data.page = document.getElementById('option-page').getAttribute('data-active');
data.html = html; data.featured = document.getElementById('option-feature').getAttribute('data-active');
data.created = document.getElementById('post-date').value; data.published = document
data.tags = document.getElementById('post_tags').value; .getElementById('option-published')
data.page = document.getElementById('option-page').getAttribute('data-active') .getAttribute('data-active');
data.featured = document.getElementById('option-feature').getAttribute('data-active') if (files.length != 0) {
data.published = document.getElementById('option-published').getAttribute('data-active') for (var i = 0; i < files.length; i++) {
if (files.length != 0) var file = files[i];
{ // Check the file type.
for (var i = 0; i < files.length; i++) if (!file.type.match('image.*')) {
{ continue;
var file = files[i]; }
// Check the file type. data.feature =
if (!file.type.match('image.*')) '/content/blog-images/' +
{ self.dateUtils.getDate('year', new Date()) +
continue; '/' +
} self.dateUtils.getDate('month', new Date()) +
data.feature = "/content/blog-images/" + self.dateUtils.getDate('year', new Date()) + "/" + self.dateUtils.getDate('month', new Date()) + "/" + file.name; '/' +
} file.name;
} }
else } else {
{ if (typeof data.feature == 'undefined') data.feature = '';
if (typeof data.feature == 'undefined') data.feature = "" }
} if (id == null) {
if (id == null) freshData = {
{ id: lastKey + 1,
freshData = { post: {
id: lastKey + 1, uuid: uuidv4(),
post: title: data.title,
{ slug: data.slug,
uuid: uuidv4(), plaintext: data.plaintext,
title: data.title, html: data.html,
slug: data.slug, feature: data.feature,
plaintext: data.plaintext, created: data.created,
html: data.html, tags: data.tags,
feature: data.feature, page: data.page,
created: data.created, featured: data.featured,
tags: data.tags, published: data.published,
page: data.page, deleted: '',
featured: data.featured, author: 'user'
published: data.published, }
deleted: "", };
author: "user" } else {
} freshData = data;
} }
} self.dbUtils
else .modify(id, freshData)
{ .then(response => {
freshData = data; resolve(response);
} if (id != null)
self.dbUtils.modify(id, freshData).then((response) => freshData.page == 'true'
{ ? self.updateNav(true, id, freshData)
resolve(response) : self.updateNav(false, id, freshData);
if(id != null) (freshData.page == 'true') ? self.updateNav(true, id, freshData) : self.updateNav(false, id, freshData) })
.catch(err => {
}).catch((err) => reject(err);
{ });
reject(err) });
}) }
}) deletePost(id, body) {
} let self = this;
deletePost(id, body) body.deleted = new Date().toString();
{ return new Promise(function(resolve, reject) {
let self = this; self.dbUtils
body.deleted = new Date().toString(); .archivePost(id, body)
return new Promise(function(resolve, reject) .then(response => {
{ //console.log(response);
self.dbUtils.archivePost(id, body).then(response => resolve(response);
{ })
console.log(response) .catch(err => {
resolve(response) //console.log(err);
}).catch(err => reject(err);
{ });
console.log(err) });
reject(error) }
}) updateNav(add, id, post) {
}) var self = this;
} this.dataUtils
updateNav(add, id, post) .request('/api/settings/nav', DataEvent.SETTINGS_LOADED)
{ .then(response => {
var self = this; let menu = JSON.parse(response.request['response']);
this.dataUtils.request('/api/settings/nav', DataEvent.SETTINGS_LOADED).then((response) => let item = {
{ id: id,
let menu = JSON.parse(response.request['response']); uuid: post.uuid,
let item = { title: post.title,
id: id, slug: post.slug
uuid: post.uuid, };
title: post.title, if (add) {
slug: post.slug menu.push(item);
} } else {
if (add) for (let index = 0; index < menu.length; index++) {
{ if (menu[index].id == id) {
menu.push(item) menu.splice(index, 1);
} }
else }
{ }
for (let index = 0; index < menu.length; index++) self.dataUtils
{ .request(
if (menu[index].id == id) '/api/settings/nav-sync',
{ DataEvent.SETTINGS_UPDATED,
menu.splice(index, 1) REQUEST_TYPE_POST,
} CONTENT_TYPE_JSON,
} menu
} )
self.dataUtils.request('/api/settings/nav-sync', DataEvent.SETTINGS_UPDATED, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, menu).then((response) => .then(() => {
{ //console.log(response);
console.log(response) })
}).catch((err) => .catch(() => {
{ //console.log(err);
console.log(err) });
}) })
}).catch((err) => .catch(() => {
{ //console.log(err);
console.log(err); });
}); }
} //--------------------------
//-------------------------- // event handlers
// event handlers //--------------------------
//-------------------------- }
}

@ -1,92 +1,88 @@
import DataUtils, import DataUtils, {
{ REQUEST_TYPE_POST,
REQUEST_TYPE_GET, CONTENT_TYPE_JSON
REQUEST_TYPE_PUT, } from '../../../../../brain//tools/utilities/DataUtils';
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
}
from '../../../../../brain//tools/utilities/DataUtils';
import StringUtils from '../../../../../brain//tools/utilities/StringUtils';
import DateUtils from '../../../../../brain/tools/utilities/DateUtils'; import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
import * as DataEvent from '../../../../../brain/tools/events/DataEvent'; import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
export default class SettingsActions export default class SettingsActions {
{ //--------------------------
//-------------------------- // constructor
// constructor //--------------------------
//-------------------------- constructor() {
constructor() this.dataUtils = new DataUtils();
{ this.dateUtils = new DateUtils();
this.dataUtils = new DataUtils(); }
this.dateUtils = new DateUtils(); //--------------------------
} // methods
//-------------------------- //--------------------------
// methods save() {
//-------------------------- let self = this;
save() let handle = document.getElementById('settings-handle').value;
{ let email = document.getElementById('settings-email').value;
let self = this; let url = document.getElementById('settings-url').value;
let handle = document.getElementById('settings-handle').value; let title = document.getElementById('settings-title').value;
let email = document.getElementById('settings-email').value; let desc = document.getElementById('settings-desc').innerHTML;
let url = document.getElementById('settings-url').value; let privacy = document.getElementById('privacy-toggle').getAttribute('data-private');
let title = document.getElementById('settings-title').value; let background = document.getElementById('background').src;
let desc = document.getElementById('settings-desc').innerHTML; let selected = '';
let privacy = document.getElementById('privacy-toggle').getAttribute('data-private'); let selects = document.querySelectorAll('.theme-select');
let background = document.getElementById('background').src; let smtpDomain = document.getElementById('smtp-domain').value;
let selected = ""; let smtpEmail = document.getElementById('smtp-email').value;
let selects = document.querySelectorAll('.theme-select'); let smtpPass = document.getElementById('smtp-pass').value;
let smtpDomain = document.getElementById('smtp-domain').value; let mgDomain = document.getElementById('mg-domain').value;
let smtpEmail = document.getElementById('smtp-email').value; let mgKey = document.getElementById('mg-key').value;
let smtpPass = document.getElementById('smtp-pass').value; let mailActive = '';
let mgDomain = document.getElementById('mg-domain').value; let mailOptions = document.querySelectorAll('.mail-option');
let mgKey = document.getElementById('mg-key').value; var i, count;
let mailActive = ""; for (i = 0, count = selects.length; i < count; i++) {
let mailOptions = document.querySelectorAll('.mail-option'); if (selects[i].getAttribute('data-enabled') == 'true') selected = selects[i].id;
for (var i = 0, length = selects.length; i < length; i++) }
{
if (selects[i].getAttribute('data-enabled') == "true") selected = selects[i].id;
}
for (var i = 0, length = mailOptions.length; i < length; i++) for (i = 0, count = mailOptions.length; i < count; i++) {
{ if (mailOptions[i].getAttribute('data-enabled') == 'true')
if (mailOptions[i].getAttribute('data-enabled') == "true") mailActive = mailOptions[i].id; mailActive = mailOptions[i].id;
} }
let settingsData = { let settingsData = {
handle: handle, handle: handle,
email: email, email: email,
url: url, url: url,
title: title, title: title,
descriptions: desc, descriptions: desc,
background: background, background: background,
private: privacy, private: privacy,
theme: selected, theme: selected,
mailSettings:{ mailSettings: {
activeProtocol: mailActive, activeProtocol: mailActive,
smtp:{ smtp: {
domain: smtpDomain, domain: smtpDomain,
email: smtpEmail, email: smtpEmail,
password:smtpPass password: smtpPass
}, },
mailgun:{ mailgun: {
domain: mgDomain, domain: mgDomain,
key: mgKey key: mgKey
} }
} }
} };
return new Promise(function(resolve, reject) return new Promise(function(resolve, reject) {
{ self.dataUtils
self.dataUtils.request('/api/settings/sync', DataEvent.SETTINGS_UPDATED, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, settingsData).then((response) => .request(
{ '/api/settings/sync',
//console.log("RESPONSE", response) DataEvent.SETTINGS_UPDATED,
resolve(response) REQUEST_TYPE_POST,
}).catch((err) => CONTENT_TYPE_JSON,
{ settingsData
reject(err); )
}) .then(response => {
}) //console.log("RESPONSE", response)
} resolve(response);
//-------------------------- })
// event handlers .catch(err => {
//-------------------------- reject(err);
} });
});
}
//--------------------------
// event handlers
//--------------------------
}

@ -3,43 +3,39 @@ import SettingsIndex from './SettingsIndex';
import NaviIndex from './NavIndex'; import NaviIndex from './NavIndex';
export default class DashManager { export default class DashManager {
//-------------------------- //--------------------------
// constructor // constructor
//-------------------------- //--------------------------
constructor() { constructor() {
this.currentDisplay = ''; this.currentDisplay = '';
this.urlPieces = document.URL.split("/"); this.urlPieces = document.URL.split('/');
this.chooseDisplay(this.urlPieces[5], this.urlPieces[6]); this.chooseDisplay(this.urlPieces[5], this.urlPieces[6]);
} }
//-------------------------- //--------------------------
// methods // methods
//-------------------------- //--------------------------
start() { start() {}
let self = this;
}
chooseDisplay(section, page) { chooseDisplay(section, page) {
this.currentDisplay = ''; this.currentDisplay = '';
switch (section) { switch (section) {
case 'posts': case 'posts':
this.currentDisplay = new PostIndex(page); this.currentDisplay = new PostIndex(page);
break; break;
case 'settings': case 'settings':
this.currentDisplay = new SettingsIndex(); this.currentDisplay = new SettingsIndex();
break; break;
case 'navigation': case 'navigation':
this.currentDisplay = new NaviIndex(); this.currentDisplay = new NaviIndex();
break;
default:
// just chill
break;
}
this.start();
} default:
//-------------------------- // just chill
// event handlers break;
//-------------------------- }
this.start();
} }
//--------------------------
// event handlers
//--------------------------
}

@ -1,66 +1,48 @@
import NavActions from "../actions/NavActions"; import NavActions from '../actions/NavActions';
import DataUtils, import DBUtils from '../../../../../brain/tools/utilities/DBUtils';
{ export default class NavIndex {
REQUEST_TYPE_GET, //--------------------------
REQUEST_TYPE_PUT, // constructor
REQUEST_TYPE_POST, //--------------------------
REQUEST_TYPE_DELETE, constructor() {
CONTENT_TYPE_JSON, this.start();
CONTENT_TYPE_FORM //this.dataUtils = new DataUtils();
this.dbutils = new DBUtils();
}
//--------------------------
// methods
//--------------------------
start() {
Sortable.create(document.getElementById('nav-pages'), {
onUpdate: () => {
new NavActions()
.save()
.then(() => {
//console.log(r);
})
.catch(() => {
//console.log(err);
});
}
});
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) {
let id = '';
switch (e.target.id) {
case 'remove-item':
id = e.target.getAttribute('data-id');
new NavActions().removeItem(id);
break;
case 'edit-item':
window.location = '/@/dashboard/posts/edit/' + e.target.getAttribute('data-id');
break;
}
}
} }
from "../../../../../brain/tools/utilities/DataUtils";
import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
import DBUtils from "../../../../../brain/tools/utilities/DBUtils";
export default class NavIndex
{
//--------------------------
// constructor
//--------------------------
constructor()
{
this.start();
this.dataUtils = new DataUtils();
this.dbutils = new DBUtils();
}
//--------------------------
// methods
//--------------------------
start()
{
let self = this;
let menu = Sortable.create(document.getElementById("nav-pages"),
{
onUpdate: e =>
{
new NavActions().save().then(r=>{
console.log(r);
}).catch(err=>{
console.log(err)
})
}
});
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)
{
let self = this;
switch (e.target.id)
{
case "remove-item":
let id = e.target.getAttribute('data-id');
new NavActions().removeItem(id);
break
case "edit-item":
window.location = "/@/dashboard/posts/edit/" + e.target.getAttribute('data-id');
break
}
}
}

@ -1,253 +1,254 @@
//TOOLS //TOOLS
import DataUtils, import DataUtils, {
{ REQUEST_TYPE_POST,
REQUEST_TYPE_GET, CONTENT_TYPE_FORM
REQUEST_TYPE_PUT, } from '../../../../../brain/tools/utilities/DataUtils';
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
}
from '../../../../../brain/tools/utilities/DataUtils';
import * as DataEvent from '../../../../../brain/tools/events/DataEvent'; import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
import PostActions from '../actions/PostActions'; import PostActions from '../actions/PostActions';
import * as EditorEvent from '../../../../../brain/tools/events/EditorEvent'; import * as EditorEvent from '../../../../../brain/tools/events/EditorEvent';
import TinyDatePicker from 'tiny-date-picker'; import TinyDatePicker from 'tiny-date-picker';
import DateUtils from '../../../../../brain/tools/utilities/DateUtils'; import DateUtils from '../../../../../brain/tools/utilities/DateUtils';
import TextEditor from '../../../../../brain/tools/ui/TextEditor'; import TextEditor from '../../../../../brain/tools/ui/TextEditor';
import DBUtils, import DBUtils, { FINAL_KEY } from '../../../../../brain/tools/utilities/DBUtils';
{ export default class PostEditor {
FINAL_KEY //TODO - FIX POST FEATURE URLS IN DB
}
from '../../../../../brain/tools/utilities/DBUtils';
export default class PostEditor
{
//TODO - FIX POST FEATURE URLS IN DB
//-------------------------- //--------------------------
// constructor // constructor
//-------------------------- //--------------------------
constructor() constructor() {
{ let self = this;
let self = this; this.dataUtils = new DataUtils();
this.dataUtils = new DataUtils(); this.dateUtils = new DateUtils();
this.dateUtils = new DateUtils(); this.urlPieces = document.URL.split('/');
this.urlPieces = document.URL.split("/"); this.dbUtils = new DBUtils();
this.dbUtils = new DBUtils(); this.post = [];
this.post = []; this.postID = null;
this.postID = null; if (document.getElementById('post-edit-index').getAttribute('data-index')) {
if (document.getElementById('post-edit-index').getAttribute('data-index')) this.postID = document.getElementById('post-edit-index').getAttribute('data-index');
{ this.dbUtils
this.postID = document.getElementById('post-edit-index').getAttribute('data-index'); .getPost(this.postID)
this.dbUtils.getPost(this.postID).then(body => .then(body => {
{ self.post = body.post;
self.post = body.post; this.start();
this.start() })
}).catch(err => .catch();
{ } else {
//console.log(err) this.start();
}) }
} if (document.getElementById('edit-post-text')) {
else this.editor = new TextEditor(
{ document.getElementById('edit-post-text'),
this.start() document.getElementById('header').offsetHeight +
} document.getElementById('post-header').offsetHeight +
if (document.getElementById('edit-post-text')) document.getElementById('post-feature').offsetHeight
{ );
this.editor = new TextEditor(document.getElementById('edit-post-text'), document.getElementById('header').offsetHeight + document.getElementById('post-header').offsetHeight + document.getElementById('post-feature').offsetHeight); this.editor.addListener(
this.editor.addListener(EditorEvent.EDITOR_DELETE, f => this.handleEditorOptions(EditorEvent.EDITOR_DELETE), false) EditorEvent.EDITOR_DELETE,
this.editor.addListener(EditorEvent.EDITOR_UPLOAD_POST_IMAGE, f => this.handleEditorOptions(EditorEvent.EDITOR_UPLOAD_POST_IMAGE), false) () => this.handleEditorOptions(EditorEvent.EDITOR_DELETE),
this.editor.addListener(EditorEvent.EDITOR_UPDATE, f => this.handleEditorOptions(EditorEvent.EDITOR_UPDATE), false) false
this.editor.addListener(EditorEvent.EDITOR_SAVE, f => this.handleEditorOptions(EditorEvent.EDITOR_SAVE), false) );
document.getElementById('post-image-upload').addEventListener('change', e => this.editor.addListener(
{ EditorEvent.EDITOR_UPLOAD_POST_IMAGE,
self.handleImageUpload(e.target.id, e.target.files); () => this.handleEditorOptions(EditorEvent.EDITOR_UPLOAD_POST_IMAGE),
}, false); false
TinyDatePicker(document.getElementById('post-date'), );
{ this.editor.addListener(
mode: 'dp-below', EditorEvent.EDITOR_UPDATE,
format(date) () => this.handleEditorOptions(EditorEvent.EDITOR_UPDATE),
{ false
return self.dateUtils.getDate('origin', date); );
} this.editor.addListener(
}); EditorEvent.EDITOR_SAVE,
} () => this.handleEditorOptions(EditorEvent.EDITOR_SAVE),
} false
//-------------------------- );
// methods document.getElementById('post-image-upload').addEventListener(
//-------------------------- 'change',
start() e => {
{ self.handleImageUpload(e.target.id, e.target.files);
let self = this; },
if (document.getElementById('featured-image-drop')) false
{ );
document.getElementById('featured-image-drop').addEventListener('dragover', this.handleImageActions, false); TinyDatePicker(document.getElementById('post-date'), {
document.getElementById('featured-image-drop').addEventListener('drop', this.handleImageActions, false); mode: 'dp-below',
document.getElementById('featured-image-upload').addEventListener('change', e => this.handleImageActions(e), false); format(date) {
if (document.getElementById('new-feature-upload')) return self.dateUtils.getDate('origin', date);
{ }
document.getElementById('new-feature-upload').addEventListener('click', e => });
{ }
document.getElementById('featured-image-upload').click(); }
}) //--------------------------
} // methods
var optionButtons = document.querySelectorAll('.post-option-btn'); //--------------------------
for (var i = 0, length = optionButtons.length; i < length; i++) start() {
{ if (document.getElementById('featured-image-drop')) {
optionButtons[i].addEventListener('click', e => this.handlePostOptions(e), false); document
} .getElementById('featured-image-drop')
} .addEventListener('dragover', this.handleImageActions, false);
} document
//-------------------------- .getElementById('featured-image-drop')
// event handlers .addEventListener('drop', this.handleImageActions, false);
//-------------------------- document
handlePostOptions(e) .getElementById('featured-image-upload')
{ .addEventListener('change', e => this.handleImageActions(e), false);
let currentOption; if (document.getElementById('new-feature-upload')) {
switch (e.target.id) document.getElementById('new-feature-upload').addEventListener('click', () => {
{ document.getElementById('featured-image-upload').click();
case "option-page-icon": });
case "option-page": }
currentOption = document.getElementById('option-page'); var optionButtons = document.querySelectorAll('.post-option-btn');
break; for (var i = 0, length = optionButtons.length; i < length; i++) {
case "option-feature-icon": optionButtons[i].addEventListener('click', e => this.handlePostOptions(e), false);
case "option-feature": }
currentOption = document.getElementById('option-feature'); }
break; }
case "option-published-icon": //--------------------------
case "option-published": // event handlers
currentOption = document.getElementById('option-published'); //--------------------------
break; handlePostOptions(e) {
} let currentOption;
let active = currentOption.getAttribute('data-active'); switch (e.target.id) {
(active == 'false') ? currentOption.setAttribute('data-active', 'true'): currentOption.setAttribute('data-active', 'false') case 'option-page-icon':
} case 'option-page':
handleEditorOptions(e) currentOption = document.getElementById('option-page');
{ break;
let self = this; case 'option-feature-icon':
switch (e) case 'option-feature':
{ currentOption = document.getElementById('option-feature');
case EditorEvent.EDITOR_SAVE: break;
new PostActions().update(this.postID, this.post, PostEditor.uploadFiles, FINAL_KEY).then(response => case 'option-published-icon':
{ case 'option-published':
setTimeout(f => currentOption = document.getElementById('option-published');
{ break;
self.dbUtils.getPost(Number(response.response.newPost)).then(r => }
{ let active = currentOption.getAttribute('data-active');
window.location = "/@/dashboard/posts/edit/" + r.post.uuid; active == 'false'
}) ? currentOption.setAttribute('data-active', 'true')
}, 100); : currentOption.setAttribute('data-active', 'false');
}).catch(err => }
{ handleEditorOptions(e) {
//console.log("ERROR", err) let self = this;
}) switch (e) {
break case EditorEvent.EDITOR_SAVE:
case EditorEvent.EDITOR_UPDATE: new PostActions()
new PostActions().update(this.postID, this.post, PostEditor.uploadFiles, FINAL_KEY).then(response => .update(this.postID, this.post, PostEditor.uploadFiles, FINAL_KEY)
{ .then(response => {
this.editor.notify(DataEvent.POST_UPDATED, this.postID); setTimeout(() => {
}).catch(err => self.dbUtils.getPost(Number(response.response.newPost)).then(r => {
{ window.location = '/@/dashboard/posts/edit/' + r.post.uuid;
//console.log("ERRORZ", err) });
}) }, 100);
break; })
case EditorEvent.EDITOR_DELETE: .catch(() => {
if (confirm('Aye! You know you\'re deleting this post, right?')) //console.log("ERROR", err)
{ });
new PostActions().deletePost(this.postID, this.post).then((response) => break;
{ case EditorEvent.EDITOR_UPDATE:
setTimeout(f => new PostActions()
{ .update(this.postID, this.post, PostEditor.uploadFiles, FINAL_KEY)
window.location = "/@/dashboard/posts/" .then(() => {
}, 100); this.editor.notify(DataEvent.POST_UPDATED, this.postID);
}).catch((err) => })
{ .catch(() => {
console.log(err) //console.log("ERRORZ", err)
}); });
} break;
else case EditorEvent.EDITOR_DELETE:
{ if (confirm("Aye! You know you're deleting this post, right?")) {
// Do nothing! new PostActions()
} .deletePost(this.postID, this.post)
break; .then(() => {
case EditorEvent.EDITOR_UPLOAD_POST_IMAGE: setTimeout(() => {
document.getElementById('post-image-upload').click(); window.location = '/@/dashboard/posts/';
break; }, 100);
} })
} .catch(() => {});
handleImageActions(e) } else {
{ // Do nothing!
e.stopPropagation(); }
e.preventDefault(); break;
var self = this; case EditorEvent.EDITOR_UPLOAD_POST_IMAGE:
switch (e.type) document.getElementById('post-image-upload').click();
{ break;
case "dragover": }
e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. }
break; handleImageActions(e) {
case "change": e.stopPropagation();
case "drop": e.preventDefault();
(e.type == "drop") ? PostEditor.uploadFiles = e.dataTransfer.files: PostEditor.uploadFiles = e.target.files; switch (e.type) {
for (var i = 0, f; f = PostEditor.uploadFiles[i]; i++) case 'dragover':
{ e.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
// Only process image files. break;
if (!f.type.match('image.*')) case 'change':
{ case 'drop':
continue; e.type == 'drop'
} ? (PostEditor.uploadFiles = e.dataTransfer.files)
var reader = new FileReader(); : (PostEditor.uploadFiles = e.target.files);
// Closure to capture the file information. for (var i = 0, f; (f = PostEditor.uploadFiles[i]); i++) {
reader.onload = (function(theFile) // Only process image files.
{ if (!f.type.match('image.*')) {
return function(f) continue;
{ }
// Render thumbnail. var reader = new FileReader();
var image = document.createElement('img'); // Closure to capture the file information.
image.src = f.target.result; reader.onload = (function(theFile) {
image.title = escape(theFile.name); return function(f) {
var span = document.createElement('div'); // Render thumbnail.
span.innerHTML = ['<img src="', var image = document.createElement('img');
f.target.result, '" title="', image.src = f.target.result;
escape(theFile.name), '"/>' image.title = escape(theFile.name);
].join(''); var span = document.createElement('div');
document.getElementById('featured-image-drop').innerHTML = ''; span.innerHTML = [
document.getElementById('featured-image-drop').appendChild(image); '<img src="',
}; f.target.result,
})(f); '" title="',
// Read in the image file as a data URL. escape(theFile.name),
reader.readAsDataURL(f); '"/>'
} ].join('');
if (e.target.id == "featured-image-upload") this.handleImageUpload(e.target.id, PostEditor.uploadFiles); document.getElementById('featured-image-drop').innerHTML = '';
break; document.getElementById('featured-image-drop').appendChild(image);
} };
} })(f);
handleImageUpload(type, files) // Read in the image file as a data URL.
{ reader.readAsDataURL(f);
let url = "" }
let eventType = ""; if (e.target.id == 'featured-image-upload')
let self = this; this.handleImageUpload(e.target.id, PostEditor.uploadFiles);
(type == "featured-image-upload") ? url = "/api/post/add-feature-image": url = "/api/post/add-post-image"; break;
(type == "featured-image-upload") ? eventType = DataEvent.FEATURE_IMAGE_ADDED: eventType = DataEvent.POST_IMAGE_ADDED }
var imageData = new FormData(); }
for (var i = 0; i < files.length; i++) handleImageUpload(type, files) {
{ let url = '';
var file = files[i]; let eventType = '';
// Check the file type. let self = this;
if (!file.type.match('image.*')) type == 'featured-image-upload'
{ ? (url = '/api/post/add-feature-image')
continue; : (url = '/api/post/add-post-image');
} type == 'featured-image-upload'
(type == "featured-image-upload") ? imageData.append('feature_image', file, file.name): imageData.append('post_image', file, file.name); ? (eventType = DataEvent.FEATURE_IMAGE_ADDED)
} : (eventType = DataEvent.POST_IMAGE_ADDED);
this.dataUtils.request(url, eventType, REQUEST_TYPE_POST, CONTENT_TYPE_FORM, imageData).then((response) => var imageData = new FormData();
{ for (var i = 0; i < files.length; i++) {
let r = JSON.parse(response.request['response']); var file = files[i];
if (r.message == DataEvent.POST_IMAGE_ADDED) self.editor.notify(EditorEvent.EDITOR_UPLOAD_POST_IMAGE, r.url); // Check the file type.
}).catch((err) => if (!file.type.match('image.*')) {
{ continue;
//console.log(err) }
}) type == 'featured-image-upload'
} ? imageData.append('feature_image', file, file.name)
: imageData.append('post_image', file, file.name);
}
this.dataUtils
.request(url, eventType, REQUEST_TYPE_POST, CONTENT_TYPE_FORM, imageData)
.then(response => {
let r = JSON.parse(response.request['response']);
if (r.message == DataEvent.POST_IMAGE_ADDED)
self.editor.notify(EditorEvent.EDITOR_UPLOAD_POST_IMAGE, r.url);
})
.catch(() => {
//console.log(err)
});
}
} }
PostEditor.uploadFiles = []; PostEditor.uploadFiles = [];

@ -1,37 +1,30 @@
import PostEditor from './PostEditor'; import PostEditor from './PostEditor';
export default class PostIndex export default class PostIndex {
{ //--------------------------
//-------------------------- // constructor
// constructor //--------------------------
//-------------------------- constructor(page) {
constructor(page) this.currentPage = null;
{ this.choosePage(page);
this.currentPage = null; this.start();
this.choosePage(page); }
this.start(); //--------------------------
} // methods
//-------------------------- //--------------------------
// methods start() {}
//-------------------------- choosePage(page) {
start() this.currentPage = '';
{ switch (page) {
let self = this; case 'edit':
} case 'add':
choosePage(page) this.currentPage = new PostEditor();
{ break;
this.currentPage = ''; default:
switch (page) //just chill
{ break;
case "edit": }
case "add": }
this.currentPage = new PostEditor(); //--------------------------
break; // event handlers
default: //--------------------------
//just chill }
break;
}
}
//--------------------------
// event handlers
//--------------------------
}

@ -1,171 +1,152 @@
import SettingsActions from "../actions/SettingsActions"; import SettingsActions from '../actions/SettingsActions';
import DataUtils, import DataUtils, {
{ REQUEST_TYPE_POST,
REQUEST_TYPE_GET, CONTENT_TYPE_FORM
REQUEST_TYPE_PUT, } from '../../../../../brain/tools/utilities/DataUtils';
REQUEST_TYPE_POST,
REQUEST_TYPE_DELETE,
CONTENT_TYPE_JSON,
CONTENT_TYPE_FORM
}
from "../../../../../brain/tools/utilities/DataUtils";
import * as DataEvent from '../../../../../brain/tools/events/DataEvent'; import * as DataEvent from '../../../../../brain/tools/events/DataEvent';
import Mailer from '../actions/Mailer'; import Mailer from '../actions/Mailer';
export default class SettingsIndex export default class SettingsIndex {
{ //--------------------------
//-------------------------- // constructor
// constructor //--------------------------
//-------------------------- constructor() {
constructor() this.start();
{ this.dataUtils = new DataUtils();
this.start(); this.mailer = new Mailer();
this.dataUtils = new DataUtils(); }
this.mailer = new Mailer(); //--------------------------
} // methods
//-------------------------- //--------------------------
// methods start() {
//-------------------------- let self = this;
start() //handle save button
{ document.getElementById('save-toggle').addEventListener('click', () =>
let self = this; new SettingsActions()
//handle save button .save()
document.getElementById('save-toggle').addEventListener('click', f => new SettingsActions().save().then(response => .then(() => {
{ //console.log(response);
console.log(response); })
}).catch(err => .catch(() => {
{ //console.log(err);
console.log(err); })
})); );
//handle set up image uploads //handle set up image uploads
document.getElementById('avatar').addEventListener('click', e => document.getElementById('avatar').addEventListener('click', () => {
{ document.getElementById('avatar-upload').click();
document.getElementById('avatar-upload').click(); });
}) document.getElementById('background').addEventListener('click', () => {
document.getElementById('background').addEventListener('click', e => document.getElementById('background-upload').click();
{ });
document.getElementById('background-upload').click(); document.getElementById('avatar-upload').addEventListener(
}) 'change',
document.getElementById('avatar-upload').addEventListener('change', e => e => {
{ self.handleImageUpload(e.target.id, e.target.files);
self.handleImageUpload(e.target.id, e.target.files); },
}, false); false
document.getElementById('background-upload').addEventListener('change', e => );
{ document.getElementById('background-upload').addEventListener(
self.handleImageUpload(e.target.id, e.target.files); 'change',
}, false); e => {
//handle privacy toggle self.handleImageUpload(e.target.id, e.target.files);
document.getElementById("privacy-toggle").addEventListener("click", e => this.togglePrivacy(e)); },
document.getElementById("send-mail").addEventListener("click", e => this.handleMailer(e)); false
//handle theme toggle );
let themeBtns = document.querySelectorAll('.theme-select'); //handle privacy toggle
for (var i = 0, length = themeBtns.length; i < length; i++) document
{ .getElementById('privacy-toggle')
themeBtns[i].addEventListener('click', e => this.handleThemes(e)); .addEventListener('click', e => this.togglePrivacy(e));
} document.getElementById('send-mail').addEventListener('click', e => this.handleMailer(e));
//handle mail options //handle theme toggle
let mailBtn = document.querySelectorAll('.mail-option'); let themeBtns = document.querySelectorAll('.theme-select');
for (var i = 0, length = mailBtn.length; i < length; i++) for (var i = 0, length = themeBtns.length; i < length; i++) {
{ themeBtns[i].addEventListener('click', e => this.handleThemes(e));
mailBtn[i].addEventListener('click', e => this.handleMailOptions(e)); }
} //handle mail options
} let mailBtn = document.querySelectorAll('.mail-option');
//-------------------------- for (i = 0, length = mailBtn.length; i < length; i++) {
// event handlers mailBtn[i].addEventListener('click', e => this.handleMailOptions(e));
//-------------------------- }
togglePrivacy(e) }
{ //--------------------------
e.stopPropagation(); // event handlers
e.preventDefault(); //--------------------------
if (e.target.getAttribute('data-private') == "false") togglePrivacy(e) {
{ e.stopPropagation();
e.target.setAttribute('data-private', 'true'); e.preventDefault();
e.target.innerHTML = "SITE IS PUBLIC" if (e.target.getAttribute('data-private') == 'false') {
} e.target.setAttribute('data-private', 'true');
else e.target.innerHTML = 'SITE IS PUBLIC';
{ } else {
e.target.setAttribute('data-private', 'false'); e.target.setAttribute('data-private', 'false');
e.target.innerHTML = "SITE IS PRIVATE" e.target.innerHTML = 'SITE IS PRIVATE';
} }
} }
handleMailer() handleMailer() {
{ this.mailer.sendMail();
this.mailer.sendMail(); }
} handleThemes(e) {
handleThemes(e) e.stopPropagation();
{ e.preventDefault();
e.stopPropagation(); let themes = document.querySelectorAll('.theme-select');
e.preventDefault(); for (var i = 0, length = themes.length; i < length; i++) {
let themes = document.querySelectorAll('.theme-select'); e.target.id == themes[i].id
for (var i = 0, length = themes.length; i < length; i++) ? themes[i].setAttribute('data-enabled', 'true')
{ : themes[i].setAttribute('data-enabled', 'false');
(e.target.id == themes[i].id) ? themes[i].setAttribute('data-enabled', 'true'): themes[i].setAttribute('data-enabled', 'false') }
} }
} handleMailOptions(e) {
handleMailOptions(e) e.preventDefault();
{ e.stopPropagation();
e.preventDefault(); let smtp = document.getElementById('mail-smtp');
e.stopPropagation(); let mailgun = document.getElementById('mail-mg');
let smtp = document.getElementById('mail-smtp'); let mail = document.querySelectorAll('.mail-option');
let mailgun = document.getElementById('mail-mg') for (var i = 0, length = mail.length; i < length; i++) {
let mail = document.querySelectorAll('.mail-option'); if (e.target.id == mail[i].id) {
for (var i = 0, length = mail.length; i < length; i++) mail[i].setAttribute('data-enabled', 'true');
{ if (e.target.id == 'option-smtp') {
if (e.target.id == mail[i].id) smtp.setAttribute('data-enabled', 'true');
{ mailgun.setAttribute('data-enabled', 'false');
mail[i].setAttribute('data-enabled', 'true') } else if (e.target.id == 'option-none') {
if (e.target.id == "option-smtp") smtp.setAttribute('data-enabled', 'false');
{ mailgun.setAttribute('data-enabled', 'false');
smtp.setAttribute('data-enabled', 'true') } else {
mailgun.setAttribute('data-enabled', 'false') smtp.setAttribute('data-enabled', 'false');
} mailgun.setAttribute('data-enabled', 'true');
else if (e.target.id == "option-none") }
{ } else {
smtp.setAttribute('data-enabled', 'false') mail[i].setAttribute('data-enabled', 'false');
mailgun.setAttribute('data-enabled', 'false') }
} }
else }
{ handleImageUpload(type, files) {
smtp.setAttribute('data-enabled', 'false') let url = '';
mailgun.setAttribute('data-enabled', 'true') let eventType = '';
} type == 'avatar-upload'
} ? (url = '/api/settings/add-avatar')
else : (url = '/api/settings/add-feature-background');
{ var imageData = new FormData();
mail[i].setAttribute('data-enabled', 'false') for (var i = 0; i < files.length; i++) {
} var file = files[i];
} // Check the file type.
} if (!file.type.match('image.*')) {
handleImageUpload(type, files) continue;
{ }
let url = "" type == 'avatar-upload'
let eventType = ""; ? imageData.append('avatar_upload', file, file.name)
let self = this; : imageData.append('background_upload', file, file.name);
(type == "avatar-upload") ? url = "/api/settings/add-avatar": url = "/api/settings/add-feature-background"; }
var imageData = new FormData(); this.dataUtils
for (var i = 0; i < files.length; i++) .request(url, eventType, REQUEST_TYPE_POST, CONTENT_TYPE_FORM, imageData)
{ .then(response => {
var file = files[i]; let r = JSON.parse(response.request['response']);
// Check the file type. if (r.message == DataEvent.AVATAR_UPLOADED) {
if (!file.type.match('image.*')) document.getElementById('avatar').src = r.url;
{ } else {
continue; document.getElementById('background').src = r.url;
} }
(type == "avatar-upload") ? imageData.append('avatar_upload', file, file.name): imageData.append('background_upload', file, file.name); })
} .catch(() => {
this.dataUtils.request(url, eventType, REQUEST_TYPE_POST, CONTENT_TYPE_FORM, imageData).then((response) => //console.log(err)
{ });
let r = JSON.parse(response.request['response']); }
if (r.message == DataEvent.AVATAR_UPLOADED) }
{
document.getElementById('avatar').src = r.url;
}
else
{
document.getElementById('background').src = r.url;
}
}).catch((err) =>
{
//console.log(err)
})
}
}

@ -2,96 +2,73 @@
------------------------------- -------------------------------
-- Bulma -- Bulma
------------------------------- -------------------------------
**/ * */
//@import '/../../node_modules/bulma.styl/bulma.styl' @import '../../../../node_modules/bulma.styl/stylus/utilities/_all';
@import "../../../../node_modules/bulma.styl/stylus/utilities/_all" @import '../../../../node_modules/bulma.styl/stylus/grid/columns';
@import "../../../../node_modules/bulma.styl/stylus/grid/columns"
/** /**
------------------------------- -------------------------------
-- Colors -- Colors
------------------------------- -------------------------------
**/ * */
@import 'main/_colors';
@import "main/_colors"
/** /**
------------------------------- -------------------------------
-- Mixins -- Mixins
------------------------------- -------------------------------
**/ * */
@import 'main/_mixins';
@import 'main/_mixins'
/** /**
------------------------------- -------------------------------
-- Normalize -- Normalize
------------------------------- -------------------------------
**/ * */
@import 'main/_normalize' @import 'main/_normalize';
/** /**
------------------------------- -------------------------------
-- Typography -- Typography
------------------------------- -------------------------------
**/ * */
@import 'main/_typography';
@import "main/_typography"
/** /**
------------------------------- -------------------------------
-- Main Structure -- Main Structure
------------------------------- -------------------------------
**/ * */
@import 'main/_structure';
@import "main/_structure"
/** /**
------------------------------- -------------------------------
-- Index -- Index
------------------------------- -------------------------------
**/ * */
@import 'main/_index';
@import "main/_index"
/** /**
------------------------------- -------------------------------
-- Settings -- Settings
------------------------------- -------------------------------
**/ * */
@import 'main/_settings';
@import "main/_settings"
/** /**
------------------------------- -------------------------------
-- Navigation -- Navigation
------------------------------- -------------------------------
**/ * */
@import 'main/_navigation';
@import "main/_navigation"
/** /**
------------------------------- -------------------------------
-- Forms -- Forms
------------------------------- -------------------------------
**/ * */
@import 'main/_forms';
@import 'main/_forms'
/** /**
------------------------------- -------------------------------
-- Blog -- Blog
------------------------------- -------------------------------
**/ * */
@import 'main/_posts';
@import 'main/_posts'
/** /**
------------------------------- -------------------------------
-- Editor -- Editor
------------------------------- -------------------------------
**/ * */
@import 'main/_editor';
@import 'main/_editor' @import 'main/_editor-highlight';
@import 'main/_editor-highlight'

Loading…
Cancel
Save