plugged in prettier and eslint, deep cleaned code base

This commit is contained in:
Ro 2019-02-27 11:17:51 -05:00
parent cc19e14a25
commit 5decfa92e2
34 changed files with 2597 additions and 2886 deletions

69
.eslintrc Normal file
View file

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

5
.prettierignore Normal file
View file

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

17
.prettierrc Normal file
View file

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

View file

@ -2,20 +2,11 @@ import DateUtils from '../../tools/utilities/DateUtils';
import StringUtils from '../../tools/utilities/StringUtils';
import * as DataEvent from '../../tools/events/DataEvent';
import sanitize from 'sanitize-html';
import RightsManager,
{
TASK_CREATE,
TASK_UPDATE,
TASK_READ,
TASK_DELETE,
OBJECT_CLIENT_ADMIN,
OBJECT_CLIENT_USER,
OBJECT_PROJECT_CLIENT,
OBJECT_PROJECT_FOLIO,
OBJECT_BOOKMARK,
OBJECT_POST
}
from '../../tools/utilities/RightsManager';
import RightsManager, {
TASK_CREATE,
TASK_UPDATE,
OBJECT_POST
} from '../../tools/utilities/RightsManager';
const express = require('express');
const router = express.Router();
const multer = require('multer');
@ -24,227 +15,182 @@ const fs = require('fs-extra');
const Models = require('../../models');
const dateUtils = new DateUtils();
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 Op = Sequelize.Op;
const _ = require('lodash');
fs.ensureDir(uploadPath, function(err)
{
//console.log(err) // => null
// 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]);
}
fs.ensureDir(uploadPath, () => {
//console.log(err) // => null
// dir has now been created, including the directory it is to be placed in
});
var feature_upload = multer(
{
storage: storage
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({
storage: storage
}).array('feature_image');
var post_upload = multer(
{
storage: storage
var post_upload = multer({
storage: storage
}).array('post_image');
//** SYNC POSTS */
router.post("/sync", (req, res, next) =>
{
let payload = req.body;
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++)
{
const item = payload[index];
Models.FreshPost.findOne(
{
where:
{
"post":
{
[Op.contains]:
{
uuid: item.post.uuid
}
}
}
}).then(found =>
{
let buffed = sanitize(item.post.plaintext,
{
allowedTags: ['del', 'a', 'iframe', 'img', ],
allowedAttributes:
{
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,
{
html: true,
xhtmlOut: true,
});
if (!_.isEqual(item.post, found.post))
{
found.update(item).then(updated =>
{
console.log("UPDATED", updated);
}).catch(err =>
{
//console.log("***ERROR***", err);
})
}
else
{
//chilld
}
}).catch(err =>
{
//console.log("***ERRRORZ****", err);
Models.FreshPost.create(item).then(fresh =>
{
//console.log(fresh)
})
})
}
res.json(
{
message: "postsSynced"
});
}
else
{
res.json(
{
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
})
router.get('/json', function(req, res, next)
{
Models.FreshPost.findAll(
{
order: [
['id', 'DESC']
]
}).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);
})
})
router.post('/sync', (req, res) => {
let payload = req.body;
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++) {
const item = payload[index];
Models.FreshPost.findOne({
where: {
post: {
[Op.contains]: {
uuid: item.post.uuid
}
}
}
})
.then(found => {
let buffed = sanitize(item.post.plaintext, {
allowedTags: ['del', 'a', 'iframe', 'img'],
allowedAttributes: {
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, {
html: true,
xhtmlOut: true
});
if (!_.isEqual(item.post, found.post)) {
found
.update(item)
.then(() => {
//console.log('UPDATED', updated);
})
.catch(() => {
//console.log("***ERROR***", err);
});
} else {
//chilld
}
})
.catch(() => {
//console.log("***ERRRORZ****", err);
Models.FreshPost.create(item).then(() => {
//console.log(fresh)
});
});
}
res.json({
message: 'postsSynced'
});
} else {
res.json({
message: "Nah. You can't do that. Talk to the admin, sport."
});
}
});
});
router.get('/json', function(req, res) {
Models.FreshPost.findAll({
order: [['id', 'DESC']]
})
.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(() => {
//next(err);
});
});
/***
POST IMAGE
*/
router.post('/add-post-image', function(req, res, next)
{
//console.log(req.body);
if (!req.session.user) return res.json(
{
message: "You need to be logged in, champ."
});
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 (err)
{
//console.log('Error in Saving Entry: ' + err);
res.json(
{
message: err
});
throw err;
}
else
{
var postImage = req.files[0].path;
return res.json(
{
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-post-image', function(req, res) {
//console.log(req.body);
if (!req.session.user)
return res.json({
message: 'You need to be logged in, champ.'
});
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 (err) {
//console.log('Error in Saving Entry: ' + err);
res.json({
message: err
});
throw err;
} else {
var postImage = req.files[0].path;
return res.json({
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)
{
//console.log(req.body);
if (!req.session.user) return res.json(
{
message: "You need to be logged in, champ."
});
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 (err)
{
//console.log('Error in Saving Entry: ' + err);
res.json(
{
message: err
});
throw err;
}
else
{
var postImage = req.files[0].path;
return res.json(
{
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."
});
}
});
router.post('/add-feature-image', function(req, res) {
//console.log(req.body);
if (!req.session.user)
return res.json({
message: 'You need to be logged in, champ.'
});
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 (err) {
//console.log('Error in Saving Entry: ' + err);
res.json({
message: err
});
throw err;
} else {
var postImage = req.files[0].path;
return res.json({
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;

View file

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

View file

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

View file

@ -1,33 +1,37 @@
module.exports = function (sequelize, DataTypes) {
var FreshPost = sequelize.define('FreshPost', {
post: {
type: DataTypes.JSONB
}
}, {
timestamps: false,
module.exports = function(sequelize, DataTypes) {
var FreshPost = sequelize.define(
'FreshPost',
{
post: {
type: DataTypes.JSONB
}
},
{
timestamps: false,
// 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
// timestamps are enabled
paranoid: false,
// 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
// timestamps are enabled
paranoid: false,
// don't use camelcase for automatically added attributes but underscore style
// so updatedAt will be updated_at
underscored: true,
// don't use camelcase for automatically added attributes but underscore style
// so updatedAt will be updated_at
underscored: true,
// disable the modification of table names; By default, sequelize will automatically
// transform all passed model names (first parameter of define) into plural.
// if you don't want that, set the following
freezeTableName: false,
// disable the modification of table names; By default, sequelize will automatically
// transform all passed model names (first parameter of define) into plural.
// if you don't want that, set the following
freezeTableName: false,
// define the table's name
tableName: 'FreshPosts',
// define the table's name
tableName: 'FreshPosts',
// 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.
// Set to true or a string with the attribute name you want to use to enable.
version: false
});
// 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.
// Set to true or a string with the attribute name you want to use to enable.
version: false
}
);
return FreshPost;
return FreshPost;
};

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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

View file

@ -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

View file

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

View file

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

View file

@ -1,160 +1,156 @@
import * as DataEvent from '../events/DataEvent';
import DateUtils from '../utilities/DateUtils';
import {
position,
offset
}
from 'caret-pos';
import { position } from 'caret-pos';
import EventEmitter from '../events/EventEmitter';
import * as EditorEvent from '../events/EditorEvent';
class TextEditor extends EventEmitter {
/**
* Text Editor UI Component
* @constructor
* @param {object} textEditor - Text area that will edit text
* @param {number} scrollLimit - YPos where editor position will become fixed
*/
//--------------------------
// constructor
//--------------------------
constructor(textEditor, scrollLimit) {
super();
hljs.initHighlightingOnLoad();
this.dateUtils = new DateUtils();
this.textEditor = textEditor;
this.fixLimit = scrollLimit;
this.caretPos = null;
this.url = '';
let self = this;
this.setInputs();
window.addEventListener("scroll", f => {
var fixLimit = this.fixLimit;
if (window.pageYOffset >= fixLimit) {
document.getElementById('edit-control').style.position = "fixed"
} else {
document.getElementById('edit-control').style.position = "relative"
}
});
this.refresh();
}
//--------------------------
// methods
//--------------------------
setInputs() {
let self = this;
var editorButtons = document.querySelectorAll('.editor-button');
for (var i = 0, length = editorButtons.length; i < length; i++) {
editorButtons[i].addEventListener('click', e => this.handleEditorOption(e), false);
}
/**
* Text Editor UI Component
* @constructor
* @param {object} textEditor - Text area that will edit text
* @param {number} scrollLimit - YPos where editor position will become fixed
*/
//--------------------------
// constructor
//--------------------------
constructor(textEditor, scrollLimit) {
super();
hljs.initHighlightingOnLoad();
this.dateUtils = new DateUtils();
this.textEditor = textEditor;
this.fixLimit = scrollLimit;
this.caretPos = null;
this.url = '';
this.setInputs();
window.addEventListener('scroll', () => {
var fixLimit = this.fixLimit;
if (window.pageYOffset >= fixLimit) {
document.getElementById('edit-control').style.position = 'fixed';
} else {
document.getElementById('edit-control').style.position = 'relative';
}
});
this.refresh();
}
//--------------------------
// methods
//--------------------------
setInputs() {
let self = this;
var editorButtons = document.querySelectorAll('.editor-button');
for (var i = 0, length = editorButtons.length; i < length; i++) {
editorButtons[i].addEventListener('click', e => this.handleEditorOption(e), false);
}
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
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) {
let caret = position(this.textEditor).pos;
self.refresh()
position(this.textEditor, caret);
}
})
}
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;
}
}
//--------------------------
// event handlers
//--------------------------
handleEditorOption(e) {
e.preventDefault();
var self = this;
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()
}
if (text.search(htmlTagRe) > -1) {
let caret = position(this.textEditor).pos;
self.refresh();
position(this.textEditor, caret);
}
});
}
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(() => {
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;
//var 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;
}
}
//--------------------------
// event handlers
//--------------------------
handleEditorOption(e) {
e.preventDefault();
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;

View file

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

View file

@ -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;
//--------------------------
// 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 = {
windowHeight: y,
windowWidth: x
}
return dimensions;
}
//--------------------------
// event handlers
//--------------------------
var dimensions = {
windowHeight: y,
windowWidth: x
};
return dimensions;
}
//--------------------------
// event handlers
//--------------------------
}
export default DOMUtils
export default DOMUtils;

View file

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

View file

@ -1,61 +1,102 @@
class DateUtils {
//--------------------------
// constructor
//--------------------------
constructor() {}
//--------------------------
// constructor
//--------------------------
constructor() {}
//--------------------------
// methods
//--------------------------
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;
}
//--------------------------
// methods
//--------------------------
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) {
var date = new Date(seconds * 1000);
return date;
}
convertMKtime(seconds) {
var date = new Date(seconds * 1000);
return date;
}
getDate(type, rawdate) {
var day =
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) {
var day = ((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;
break;
case "month":
return month;
break;
case "year":
return year;
break;
case "stamp":
return String(year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + seconds + "." + millisecond + "-" + (offset));
break
default:
return String(year + "-" + month + "-" + day);
break;
}
}
case 'month':
return month;
case 'year':
return year;
case 'stamp':
return String(
year +
'-' +
month +
'-' +
day +
' ' +
hour +
':' +
minute +
':' +
seconds +
'.' +
millisecond +
'-' +
offset
);
default:
return String(year + '-' + month + '-' + day);
}
}
//--------------------------
// event handlers
//--------------------------
//--------------------------
// event handlers
//--------------------------
}
export default DateUtils
export default DateUtils;

View file

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

View file

@ -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;
}
//--------------------------
// constructor
//--------------------------
constructor()
{}
//--------------------------
// methods
//--------------------------
cleanString(string)
{
var clean = string.replace(/(^\-+|[^a-zA-Z0-9\/_| -]+|\-+$)/g, '').toLowerCase().replace(/[\/_| -]+/g, '-');
return clean;
}
decodeHTML(string, quote_style) {
var optTemp = 0,
i = 0,
noquotes = false;
if (typeof quote_style === 'undefined') {
quote_style = 2;
}
string = string
.toString()
.replace(/&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;
}
decodeHTML(string, quote_style) {
var optTemp = 0,
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
//--------------------------
//--------------------------
// event handlers
//--------------------------
}
export default StringUtils
export default StringUtils;

84
init.js
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,66 +1,48 @@
import NavActions from "../actions/NavActions";
import DataUtils,
{
REQUEST_TYPE_GET,
REQUEST_TYPE_PUT,
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 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
}
}
import NavActions from '../actions/NavActions';
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() {
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;
}
}
}

View file

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

View file

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

View file

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

View file

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