From 4dce90ab411ba2f132d6873636aa052e286a7be8 Mon Sep 17 00:00:00 2001 From: Scott Tolksdorf Date: Mon, 14 Nov 2016 20:14:08 -0500 Subject: [PATCH 01/17] Cleaning up the server file --- server.js | 147 +++++++++++++++++------------------------ server/admin.api.js | 72 ++++++++++++++++++++ server/homebrew.api.js | 140 ++++++++++++++++++--------------------- 3 files changed, 197 insertions(+), 162 deletions(-) create mode 100644 server/admin.api.js diff --git a/server.js b/server.js index 763f98aa9..d3adab5a0 100644 --- a/server.js +++ b/server.js @@ -1,114 +1,66 @@ -'use strict'; -var _ = require('lodash'); require('app-module-path').addPath('./shared'); -var vitreumRender = require('vitreum/render'); -var bodyParser = require('body-parser') -var express = require("express"); -var app = express(); + +const _ = require('lodash'); + +const vitreumRender = require('vitreum/render'); +const bodyParser = require('body-parser') +const express = require("express"); +const app = express(); app.use(express.static(__dirname + '/build')); app.use(bodyParser.json({limit: '25mb'})); + + //Mongoose -var mongoose = require('mongoose'); -var mongoUri = process.env.MONGODB_URI || process.env.MONGOLAB_URI || 'mongodb://localhost/naturalcrit'; -mongoose.connect(mongoUri); +//TODO: Celean up +const mongoose = require('mongoose'); +const mongoUri = process.env.MONGODB_URI || process.env.MONGOLAB_URI || 'mongodb://localhost/naturalcrit'; +require('mongoose').connect(mongoUri); mongoose.connection.on('error', function(){ console.log(">>>ERROR: Run Mongodb.exe ya goof!"); }); -//Admin route -process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; -process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password'; -process.env.ADMIN_KEY = process.env.ADMIN_KEY || 'admin_key'; -var auth = require('basic-auth'); -app.get('/admin', function(req, res){ - var credentials = auth(req) - if (!credentials || credentials.name !== process.env.ADMIN_USER || credentials.pass !== process.env.ADMIN_PASS) { - res.setHeader('WWW-Authenticate', 'Basic realm="example"') - return res.status(401).send('Access denied') - } - vitreumRender({ - page: './build/admin/bundle.dot', - prerenderWith : './client/admin/admin.jsx', - clearRequireCache : !process.env.PRODUCTION, - initialProps: { - url: req.originalUrl, - admin_key : process.env.ADMIN_KEY, - }, - }, function (err, page) { - return res.send(page) - }); -}); + +app.use(require('./server/homebrew.api.js')); +app.use(require('./server/admin.api.js')); -//Populate homebrew routes -app = require('./server/homebrew.api.js')(app); +const HomebrewModel = require('./server/homebrew.model.js').model; +const welcomeText = require('fs').readFileSync('./client/homebrew/pages/homePage/welcome_msg.md', 'utf8'); +const changelogText = require('fs').readFileSync('./changelog.md', 'utf8'); -var HomebrewModel = require('./server/homebrew.model.js').model; - var sanitizeBrew = function(brew){ var cleanBrew = _.assign({}, brew); delete cleanBrew.editId; return cleanBrew; }; -//Load project version -var projectVersion = require('./package.json').version; - -//Edit Page -app.get('/edit/:id', function(req, res){ - HomebrewModel.find({editId : req.params.id}, function(err, objs){ - var resObj = null; - if(objs.length){ - resObj = objs[0].toJSON(); +app.get('/edit/:id', (req, res, next)=>{ + HomebrewModel.find({editId : req.params.id}, (err, brews)=>{ + if(err || !brews.length){ + return res.status(400).send(`Can't get that`); } - - vitreumRender({ - page: './build/homebrew/bundle.dot', - globals:{}, - prerenderWith : './client/homebrew/homebrew.jsx', - initialProps: { - url: req.originalUrl, - brew : resObj || {}, - version : projectVersion - }, - clearRequireCache : !process.env.PRODUCTION, - }, function (err, page) { - return res.send(page) - }); + req.brew = brews[0].toJSON(); + return next(); }) }); //Share Page -app.get('/share/:id', function(req, res){ - HomebrewModel.find({shareId : req.params.id}, function(err, objs){ - var brew = {}; - - if(objs.length){ - var resObj = objs[0]; - resObj.lastViewed = new Date(); - resObj.views = resObj.views + 1; - resObj.save(); - - brew = resObj.toJSON(); +app.get('/share/:id', (req, res, next)=>{ + HomebrewModel.find({shareId : req.params.id}, (err, brews)=>{ + if(err || !brews.length){ + return res.status(400).send(`Can't get that`); } + const brew = brews[0]; + brew.lastViewed = new Date(); + brew.views = brew.views + 1; + brew.save(); - vitreumRender({ - page: './build/homebrew/bundle.dot', - globals:{}, - prerenderWith : './client/homebrew/homebrew.jsx', - initialProps: { - url: req.originalUrl, - brew : sanitizeBrew(brew || {}), - version : projectVersion - }, - clearRequireCache : !process.env.PRODUCTION, - }, function (err, page) { - return res.send(page) - }); + req.brew = sanitizeBrew(brew); + return next(); }) }); @@ -152,9 +104,10 @@ app.get('/source/:id', function(req, res){ }); }); + +/* //Home and 404, etc. -var welcomeText = require('fs').readFileSync('./client/homebrew/pages/homePage/welcome_msg.md', 'utf8'); -var changelogText = require('fs').readFileSync('./changelog.md', 'utf8'); + app.get('*', function (req, res) { vitreumRender({ page: './build/homebrew/bundle.dot', @@ -171,6 +124,30 @@ app.get('*', function (req, res) { return res.send(page) }); }); +*/ + + +//Render Page +app.use((req, res) => { + vitreumRender({ + page: './build/homebrew/bundle.dot', + globals:{ + version : require('./package.json').version + }, + prerenderWith : './client/homebrew/homebrew.jsx', + initialProps: { + url: req.originalUrl, + + welcomeText : welcomeText, + changelog : changelogText, + brew : req.brew + }, + clearRequireCache : !process.env.PRODUCTION, + }, (err, page) => { + return res.send(page) + }); +}); + diff --git a/server/admin.api.js b/server/admin.api.js new file mode 100644 index 000000000..8739ce6d0 --- /dev/null +++ b/server/admin.api.js @@ -0,0 +1,72 @@ +const _ = require('lodash'); +const auth = require('basic-auth'); +const HomebrewModel = require('./homebrew.model.js').model; +const router = require('express').Router(); +const vitreumRender = require('vitreum/render'); + + +const mw = { + adminOnly : (req, res, next)=>{ + if(req.query && req.query.admin_key == process.env.ADMIN_KEY) return next(); + return res.status(401).send('Access denied'); + } +}; + +process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; +process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password'; +process.env.ADMIN_KEY = process.env.ADMIN_KEY || 'admin_key'; + + + +//Removes all empty brews that are older than 3 days and that are shorter than a tweet +router.get('/api/invalid', mw.adminOnly, (req, res)=>{ + const invalidBrewQuery = HomebrewModel.find({ + '$where' : "this.text.length < 140", + createdAt: { + $lt: Moment().subtract(3, 'days').toDate() + } + }); + + if(req.query.do_it){ + invalidBrewQuery.remove().exec((err, objs)=>{ + refreshCount(); + return res.send(200); + }) + }else{ + invalidBrewQuery.exec((err, objs)=>{ + if(err) console.log(err); + return res.json({ + count : objs.length + }) + }) + } +}); + + + +//Admin route + + +router.get('/admin', function(req, res){ + const credentials = auth(req) + if (!credentials || credentials.name !== process.env.ADMIN_USER || credentials.pass !== process.env.ADMIN_PASS) { + res.setHeader('WWW-Authenticate', 'Basic realm="example"') + return res.status(401).send('Access denied') + } + vitreumRender({ + page: './build/admin/bundle.dot', + prerenderWith : './client/admin/admin.jsx', + clearRequireCache : !process.env.PRODUCTION, + initialProps: { + url: req.originalUrl, + admin_key : process.env.ADMIN_KEY, + }, + }, function (err, page) { + return res.send(page) + }); +}); + + + + +module.exports = router; \ No newline at end of file diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 2e031b6c8..84cf06c66 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -1,36 +1,33 @@ -var _ = require('lodash'); -var Moment = require('moment'); -var HomebrewModel = require('./homebrew.model.js').model; +const _ = require('lodash'); +const Moment = require('moment'); +const HomebrewModel = require('./homebrew.model.js').model; +const router = require('express').Router(); -var homebrewTotal = 0; -var refreshCount = function(){ - HomebrewModel.count({}, function(err, total){ + + +//TODO: Possiblity remove +let homebrewTotal = 0; +const refreshCount = ()=>{ + HomebrewModel.count({}, (err, total)=>{ homebrewTotal = total; }); }; -refreshCount() - -var mw = { - adminOnly : function(req, res, next){ - if(req.query && req.query.admin_key == process.env.ADMIN_KEY){ - next(); - }else{ - return res.status(401).send('Access denied'); - } - } -}; +refreshCount(); -var getTopBrews = function(cb){ + + + +const getTopBrews = (cb)=>{ HomebrewModel.find().sort({views: -1}).limit(5).exec(function(err, brews) { cb(brews); }); } -var getGoodBrewTitle = (text) => { - var titlePos = text.indexOf('# '); +const getGoodBrewTitle = (text) => { + const titlePos = text.indexOf('# '); if(titlePos !== -1){ - var ending = text.indexOf('\n', titlePos); + const ending = text.indexOf('\n', titlePos); return text.substring(titlePos + 2, ending); }else{ return _.find(text.split('\n'), (line)=>{ @@ -40,70 +37,58 @@ var getGoodBrewTitle = (text) => { }; -module.exports = function(app){ - app.post('/api', function(req, res){ - var newHomebrew = new HomebrewModel(req.body); - if(!newHomebrew.title){ - newHomebrew.title = getGoodBrewTitle(newHomebrew.text); +router.post('/api', (req, res)=>{ + const newHomebrew = new HomebrewModel(req.body); + if(!newHomebrew.title){ + newHomebrew.title = getGoodBrewTitle(newHomebrew.text); + } + newHomebrew.save((err, obj)=>{ + if(err){ + console.error(err, err.toString(), err.stack); + return res.status(500).send(`Error while creating new brew, ${err.toString()}`); } - newHomebrew.save(function(err, obj){ - if(err){ - console.error(err, err.toString(), err.stack); - return res.status(500).send(`Error while creating new brew, ${err.toString()}`); - } - return res.json(obj); + return res.json(obj); + }) +}); + +router.put('/api/update/:id', (req, res)=>{ + HomebrewModel.find({editId : req.params.id}, (err, objs)=>{ + if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); + var resEntry = objs[0]; + resEntry.text = req.body.text; + resEntry.title = req.body.title; + resEntry.updatedAt = new Date(); + resEntry.save((err, obj)=>{ + if(err) return res.status(500).send("Error while saving"); + return res.status(200).send(obj); }) }); +}); - app.put('/api/update/:id', function(req, res){ - HomebrewModel.find({editId : req.params.id}, function(err, objs){ - if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); - var resEntry = objs[0]; - resEntry.text = req.body.text; - resEntry.title = req.body.title; - resEntry.updatedAt = new Date(); - resEntry.save(function(err, obj){ - if(err) return res.status(500).send("Error while saving"); - return res.status(200).send(obj); - }) - }); +router.get('/api/remove/:id', (req, res)=>{ + HomebrewModel.find({editId : req.params.id}, (err, objs)=>{ + if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); + var resEntry = objs[0]; + resEntry.remove((err)=>{ + if(err) return res.status(500).send("Error while removing"); + return res.status(200).send(); + }) }); +}); - app.get('/api/remove/:id', function(req, res){ - HomebrewModel.find({editId : req.params.id}, function(err, objs){ - if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); - var resEntry = objs[0]; - resEntry.remove(function(err){ - if(err) return res.status(500).send("Error while removing"); - return res.status(200).send(); - }) - }); - }); - //Removes all empty brews that are older than 3 days and that are shorter than a tweet - app.get('/api/invalid', mw.adminOnly, function(req, res){ - var invalidBrewQuery = HomebrewModel.find({ - '$where' : "this.text.length < 140", - createdAt: { - $lt: Moment().subtract(3, 'days').toDate() - } - }); +module.exports = router; + +/* + + + +module.exports = function(app){ + + app; + - if(req.query.do_it){ - invalidBrewQuery.remove().exec((err, objs)=>{ - refreshCount(); - return res.send(200); - }) - }else{ - invalidBrewQuery.exec((err, objs)=>{ - if(err) console.log(err); - return res.json({ - count : objs.length - }) - }) - } - }); app.get('/api/search', mw.adminOnly, function(req, res){ @@ -143,4 +128,5 @@ module.exports = function(app){ return app; -} \ No newline at end of file +} +*/ \ No newline at end of file From d7463ec28e1fc5a2ff795ddb330133e7001f857b Mon Sep 17 00:00:00 2001 From: Scott Tolksdorf Date: Mon, 14 Nov 2016 20:15:29 -0500 Subject: [PATCH 02/17] Navbar now using global scope --- client/homebrew/navbar/navbar.jsx | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/client/homebrew/navbar/navbar.jsx b/client/homebrew/navbar/navbar.jsx index 0aeac86c5..ae4604598 100644 --- a/client/homebrew/navbar/navbar.jsx +++ b/client/homebrew/navbar/navbar.jsx @@ -1,25 +1,21 @@ -var React = require('react'); -var _ = require('lodash'); +const React = require('react'); +const _ = require('lodash'); -var Nav = require('naturalcrit/nav/nav.jsx'); +const Nav = require('naturalcrit/nav/nav.jsx'); -var Navbar = React.createClass({ - getDefaultProps: function() { +const Navbar = React.createClass({ + getInitialState: function() { return { + showNonChromeWarning : false, ver : '0.0.0' }; }, - getInitialState: function() { - return { - showNonChromeWarning : false - }; - }, - componentDidMount: function() { - var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); + const isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); this.setState({ - showNonChromeWarning : !isChrome + showNonChromeWarning : !isChrome, + ver : window.version }) }, @@ -40,7 +36,7 @@ var Navbar = React.createClass({
The Homebrewery
- {`v${this.props.ver}`} + {`v${this.state.ver}`} {this.renderChromeWarning()} From 6672dff93811b28cfede3f533c98f843ad09d07c Mon Sep 17 00:00:00 2001 From: Scott Tolksdorf Date: Mon, 14 Nov 2016 21:31:01 -0500 Subject: [PATCH 03/17] Print page can now load from local storage --- client/homebrew/homebrew.jsx | 17 ++++--- client/homebrew/homebrew.less | 3 +- client/homebrew/pages/newPage/newPage.jsx | 12 +++++ client/homebrew/pages/printPage/printPage.jsx | 50 +++++++++++++++++++ .../homebrew/pages/printPage/printPage.less | 3 ++ server.js | 50 +++++++------------ server/homebrew.model.js | 2 +- 7 files changed, 95 insertions(+), 42 deletions(-) create mode 100644 client/homebrew/pages/printPage/printPage.jsx create mode 100644 client/homebrew/pages/printPage/printPage.less diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx index ae711cda9..05a31c65e 100644 --- a/client/homebrew/homebrew.jsx +++ b/client/homebrew/homebrew.jsx @@ -9,6 +9,7 @@ var EditPage = require('./pages/editPage/editPage.jsx'); var SharePage = require('./pages/sharePage/sharePage.jsx'); var NewPage = require('./pages/newPage/newPage.jsx'); var ErrorPage = require('./pages/errorPage/errorPage.jsx'); +var PrintPage = require('./pages/printPage/printPage.jsx'); var Router; var Homebrew = React.createClass({ @@ -32,35 +33,37 @@ var Homebrew = React.createClass({ Router = CreateRouter({ '/edit/:id' : (args) => { if(!this.props.brew.editId){ - return + return } return }, '/share/:id' : (args) => { if(!this.props.brew.shareId){ - return + return } return }, '/changelog' : (args) => { return }, + '/print/:id' : (args, query) => { + return ; + }, + '/print' : (args, query) => { + return ; + }, '/new' : (args) => { - return + return }, '*' : , }); }, diff --git a/client/homebrew/homebrew.less b/client/homebrew/homebrew.less index 00deebe5b..6b9423d55 100644 --- a/client/homebrew/homebrew.less +++ b/client/homebrew/homebrew.less @@ -2,11 +2,10 @@ .homebrew{ height : 100%; - //TODO: Consider making backgroudn color lighter - background-color : @steel; .page{ display : flex; height : 100%; + background-color : @steel; flex-direction : column; .content{ position : relative; diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 6e4763222..b2a9f634e 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -91,6 +91,17 @@ const NewPage = React.createClass({ } }, + handlePrintClick : function(){ + localStorage.setItem('print', this.state.text); + window.open('/print?dialog=true&local=print','_blank'); + }, + + renderLocalPrintButton : function(){ + return + get PDF + + }, + renderNavbar : function(){ return @@ -99,6 +110,7 @@ const NewPage = React.createClass({ {this.renderSaveButton()} + {this.renderLocalPrintButton()} diff --git a/client/homebrew/pages/printPage/printPage.jsx b/client/homebrew/pages/printPage/printPage.jsx new file mode 100644 index 000000000..6aa292223 --- /dev/null +++ b/client/homebrew/pages/printPage/printPage.jsx @@ -0,0 +1,50 @@ +const React = require('react'); +const _ = require('lodash'); +const cx = require('classnames'); + +//const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); + +var Markdown = require('naturalcrit/markdown.js'); + +const PrintPage = React.createClass({ + getDefaultProps: function() { + return { + query : {}, + brew : { + text : '', + } + }; + }, + + getInitialState: function() { + return { + brewText: this.props.brew.text + }; + }, + + componentDidMount: function() { + if(this.props.query.local){ + this.setState({ brewText : localStorage.getItem(this.props.query.local)}); + } + + if(this.props.query.dialog) window.print(); + }, + + renderPages : function(){ + return _.map(this.state.brewText.split('\\page'), (page, index) => { + return
; + }); + }, + + render : function(){ + return
+ {this.renderPages()} +
+ } +}); + +module.exports = PrintPage; diff --git a/client/homebrew/pages/printPage/printPage.less b/client/homebrew/pages/printPage/printPage.less new file mode 100644 index 000000000..0d9e7b68b --- /dev/null +++ b/client/homebrew/pages/printPage/printPage.less @@ -0,0 +1,3 @@ +.printPage{ + +} \ No newline at end of file diff --git a/server.js b/server.js index d3adab5a0..514a83612 100644 --- a/server.js +++ b/server.js @@ -1,7 +1,6 @@ require('app-module-path').addPath('./shared'); const _ = require('lodash'); - const vitreumRender = require('vitreum/render'); const bodyParser = require('body-parser') const express = require("express"); @@ -10,7 +9,6 @@ app.use(express.static(__dirname + '/build')); app.use(bodyParser.json({limit: '25mb'})); - //Mongoose //TODO: Celean up const mongoose = require('mongoose'); @@ -59,11 +57,23 @@ app.get('/share/:id', (req, res, next)=>{ brew.views = brew.views + 1; brew.save(); - req.brew = sanitizeBrew(brew); + req.brew = sanitizeBrew(brew.toJSON()); return next(); }) }); +//Share Page +app.get('/print/:id', (req, res, next)=>{ + HomebrewModel.find({shareId : req.params.id}, (err, brews)=>{ + if(err || !brews.length){ + return res.status(400).send(`Can't get that`); + } + req.brew = sanitizeBrew(brews[0].toJSON()); + return next(); + }) +}); + +/* //Print Page var Markdown = require('naturalcrit/markdown.js'); var PHBStyle = '' @@ -91,42 +101,19 @@ app.get('/print/:id', function(req, res){ return res.send(page) }); }); +*/ //Source page String.prototype.replaceAll = function(s,r){return this.split(s).join(r)} -app.get('/source/:id', function(req, res){ - HomebrewModel.find({shareId : req.params.id}, function(err, objs){ - if(err || !objs.length) return res.status(404).send('Could not find Homebrew with that id'); - var brew = null; - if(objs.length) brew = objs[0]; - var text = brew.text.replaceAll('<', '<').replaceAll('>', '>'); +app.get('/source/:id', (req, res)=>{ + HomebrewModel.find({shareId : req.params.id}, (err, brews)=>{ + if(err || !brews.length) return res.status(404).send('Could not find Homebrew with that id'); + const text = brews[0].text.replaceAll('<', '<').replaceAll('>', '>'); return res.send(`
${text}
`); }); }); -/* -//Home and 404, etc. - -app.get('*', function (req, res) { - vitreumRender({ - page: './build/homebrew/bundle.dot', - globals:{}, - prerenderWith : './client/homebrew/homebrew.jsx', - initialProps: { - url: req.originalUrl, - welcomeText : welcomeText, - changelog : changelogText, - version : projectVersion - }, - clearRequireCache : !process.env.PRODUCTION, - }, function (err, page) { - return res.send(page) - }); -}); -*/ - - //Render Page app.use((req, res) => { vitreumRender({ @@ -137,7 +124,6 @@ app.use((req, res) => { prerenderWith : './client/homebrew/homebrew.jsx', initialProps: { url: req.originalUrl, - welcomeText : welcomeText, changelog : changelogText, brew : req.brew diff --git a/server/homebrew.model.js b/server/homebrew.model.js index e7d89b9cb..7dcd58270 100644 --- a/server/homebrew.model.js +++ b/server/homebrew.model.js @@ -12,7 +12,7 @@ var HomebrewSchema = mongoose.Schema({ updatedAt : { type: Date, default: Date.now}, lastViewed : { type: Date, default: Date.now}, views : {type:Number, default:0} -}); +}, { versionKey: false }); From 8b3f9ac76ae5c26f8b81913529351103c2b35780 Mon Sep 17 00:00:00 2001 From: Scott Tolksdorf Date: Mon, 14 Nov 2016 22:30:28 -0500 Subject: [PATCH 04/17] Cleaned up the server file and added methodfs and statics to the model --- client/homebrew/homebrew.jsx | 24 ++-- client/homebrew/pages/printPage/printPage.jsx | 5 +- server.js | 125 ++++++++---------- server/homebrew.api.js | 22 +-- server/homebrew.model.js | 35 +++++ 5 files changed, 113 insertions(+), 98 deletions(-) diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx index 05a31c65e..6d45aac68 100644 --- a/client/homebrew/homebrew.jsx +++ b/client/homebrew/homebrew.jsx @@ -1,18 +1,18 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); +const React = require('react'); +const _ = require('lodash'); +const cx = require('classnames'); -var CreateRouter = require('pico-router').createRouter; +const CreateRouter = require('pico-router').createRouter; -var HomePage = require('./pages/homePage/homePage.jsx'); -var EditPage = require('./pages/editPage/editPage.jsx'); -var SharePage = require('./pages/sharePage/sharePage.jsx'); -var NewPage = require('./pages/newPage/newPage.jsx'); -var ErrorPage = require('./pages/errorPage/errorPage.jsx'); -var PrintPage = require('./pages/printPage/printPage.jsx'); +const HomePage = require('./pages/homePage/homePage.jsx'); +const EditPage = require('./pages/editPage/editPage.jsx'); +const SharePage = require('./pages/sharePage/sharePage.jsx'); +const NewPage = require('./pages/newPage/newPage.jsx'); +const ErrorPage = require('./pages/errorPage/errorPage.jsx'); +const PrintPage = require('./pages/printPage/printPage.jsx'); -var Router; -var Homebrew = React.createClass({ +let Router; +const Homebrew = React.createClass({ getDefaultProps: function() { return { url : '', diff --git a/client/homebrew/pages/printPage/printPage.jsx b/client/homebrew/pages/printPage/printPage.jsx index 6aa292223..b6ecfd89d 100644 --- a/client/homebrew/pages/printPage/printPage.jsx +++ b/client/homebrew/pages/printPage/printPage.jsx @@ -1,10 +1,7 @@ const React = require('react'); const _ = require('lodash'); const cx = require('classnames'); - -//const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); - -var Markdown = require('naturalcrit/markdown.js'); +const Markdown = require('naturalcrit/markdown.js'); const PrintPage = React.createClass({ getDefaultProps: function() { diff --git a/server.js b/server.js index 514a83612..fb11c0cd5 100644 --- a/server.js +++ b/server.js @@ -35,85 +35,66 @@ var sanitizeBrew = function(brew){ }; -app.get('/edit/:id', (req, res, next)=>{ - HomebrewModel.find({editId : req.params.id}, (err, brews)=>{ - if(err || !brews.length){ - return res.status(400).send(`Can't get that`); - } - req.brew = brews[0].toJSON(); - return next(); - }) -}); - - -//Share Page -app.get('/share/:id', (req, res, next)=>{ - HomebrewModel.find({shareId : req.params.id}, (err, brews)=>{ - if(err || !brews.length){ - return res.status(400).send(`Can't get that`); - } - const brew = brews[0]; - brew.lastViewed = new Date(); - brew.views = brew.views + 1; - brew.save(); - - req.brew = sanitizeBrew(brew.toJSON()); - return next(); - }) -}); - -//Share Page -app.get('/print/:id', (req, res, next)=>{ - HomebrewModel.find({shareId : req.params.id}, (err, brews)=>{ - if(err || !brews.length){ - return res.status(400).send(`Can't get that`); - } - req.brew = sanitizeBrew(brews[0].toJSON()); - return next(); - }) -}); - -/* -//Print Page -var Markdown = require('naturalcrit/markdown.js'); -var PHBStyle = '' -app.get('/print/:id', function(req, res){ - HomebrewModel.find({shareId : req.params.id}, function(err, objs){ - var brew = {}; - if(objs.length){ - brew = objs[0]; - } - - if(err || !objs.length){ - brew.text = '# Oops \n We could not find a brew with that id. **Sorry!**'; - } - - var content = _.map(brew.text.split('\\page'), function(pageText, index){ - return `
` + Markdown.render(pageText) + '
'; - }).join('\n'); - - var dialog = ''; - if(req.query && req.query.dialog) dialog = 'onload="window.print()"'; - - var title = '' + brew.title + ''; - var page = `${title} ${PHBStyle}${content}` - - return res.send(page) - }); -}); -*/ //Source page String.prototype.replaceAll = function(s,r){return this.split(s).join(r)} app.get('/source/:id', (req, res)=>{ - HomebrewModel.find({shareId : req.params.id}, (err, brews)=>{ - if(err || !brews.length) return res.status(404).send('Could not find Homebrew with that id'); - const text = brews[0].text.replaceAll('<', '<').replaceAll('>', '>'); - return res.send(`
${text}
`); - }); + HomebrewModel.get({shareId : req.params.id}) + .then((brew)=>{ + const text = brew.text.replaceAll('<', '<').replaceAll('>', '>'); + return res.send(`
${text}
`); + }) + .catch((err)=>{ + console.log(err); + return res.status(404).send('Could not find Homebrew with that id'); + }) }); +app.get('/edit/:id', (req, res, next)=>{ + HomebrewModel.get({editId : req.params.id}) + .then((brew)=>{ + req.brew = brew.sanatize(); + return next(); + }) + .catch((err)=>{ + console.log(err); + return res.status(400).send(`Can't get that`); + }); +}); + +//Share Page +app.get('/share/:id', (req, res, next)=>{ + HomebrewModel.get({shareId : req.params.id}) + .then((brew)=>{ + return brew.increaseView(); + }) + .then((brew)=>{ + req.brew = brew.sanatize(true); + return next(); + }) + .catch((err)=>{ + console.log(err); + return res.status(400).send(`Can't get that`); + }); +}); + +//Print Page +app.get('/print/:id', (req, res, next)=>{ + HomebrewModel.get({shareId : req.params.id}) + .then((brew)=>{ + req.brew = brew.sanatize(true); + return next(); + }) + .catch((err)=>{ + console.log(err); + return res.status(400).send(`Can't get that`); + }); +}); + + + + //Render Page app.use((req, res) => { vitreumRender({ diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 84cf06c66..9322327fe 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -53,17 +53,19 @@ router.post('/api', (req, res)=>{ }); router.put('/api/update/:id', (req, res)=>{ - HomebrewModel.find({editId : req.params.id}, (err, objs)=>{ - if(!objs.length || err) return res.status(404).send("Can not find homebrew with that id"); - var resEntry = objs[0]; - resEntry.text = req.body.text; - resEntry.title = req.body.title; - resEntry.updatedAt = new Date(); - resEntry.save((err, obj)=>{ - if(err) return res.status(500).send("Error while saving"); - return res.status(200).send(obj); + HomebrewModel.get({editId : req.params.id}) + .then((brew)=>{ + brew = _.merge(brew, req.body); + brew.updatedAt = new Date(); + brew.save((err, obj)=>{ + if(err) throw err; + return res.status(200).send(obj); + }) }) - }); + .catch((err)=>{ + console.log(err); + return res.status(500).send("Error while saving"); + }); }); router.get('/api/remove/:id', (req, res)=>{ diff --git a/server/homebrew.model.js b/server/homebrew.model.js index 7dcd58270..abb9bf14e 100644 --- a/server/homebrew.model.js +++ b/server/homebrew.model.js @@ -7,6 +7,7 @@ var HomebrewSchema = mongoose.Schema({ editId : {type : String, default: shortid.generate, index: { unique: true }}, title : {type : String, default : ""}, text : {type : String, default : ""}, + authors : [String], createdAt : { type: Date, default: Date.now }, updatedAt : { type: Date, default: Date.now}, @@ -16,6 +17,40 @@ var HomebrewSchema = mongoose.Schema({ +HomebrewSchema.methods.sanatize = function(full=false){ + const brew = this.toJSON(); + delete brew._id; + delete brew.__v; + if(full){ + delete brew.editId; + } + return brew; +}; + + +HomebrewSchema.methods.increaseView = function(){ + return new Promise((resolve, reject) => { + this.lastViewed = new Date(); + this.views = this.views + 1; + this.save((err) => { + if(err) return reject(err); + return resolve(this); + }); + }); +}; + + + +HomebrewSchema.statics.get = function(query){ + return new Promise((resolve, reject) => { + Homebrew.find(query, (err, brews)=>{ + if(err || !brews.length) return reject('Can not find brew'); + return resolve(brews[0]); + }); + }); +}; + + var Homebrew = mongoose.model('Homebrew', HomebrewSchema); module.exports = { From 2f2a1c51465aea283b812e75eaef5e28e4be701d Mon Sep 17 00:00:00 2001 From: Scott Tolksdorf Date: Mon, 14 Nov 2016 22:40:37 -0500 Subject: [PATCH 05/17] Control s and p now save and print on editor pages --- client/homebrew/pages/editPage/editPage.jsx | 16 +++++++++++--- client/homebrew/pages/hijackPrint.js | 2 ++ client/homebrew/pages/newPage/newPage.jsx | 23 +++++++++++++++++---- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index de1278dba..27cacddf8 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -16,7 +16,6 @@ var SplitPane = require('naturalcrit/splitPane/splitPane.jsx'); var Editor = require('../../editor/editor.jsx'); var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); -var HijackPrint = require('../hijackPrint.js'); var Markdown = require('naturalcrit/markdown.js'); @@ -65,11 +64,22 @@ var EditPage = React.createClass({ htmlErrors : Markdown.validate(this.state.text) }) - document.onkeydown = HijackPrint(this.props.brew.shareId); + document.addEventListener('keydown', this.handleControlKeys); }, componentWillUnmount: function() { window.onbeforeunload = function(){}; - document.onkeydown = function(){}; + document.removeEventListener('keydown', this.handleControlKeys); + }, + + + handleControlKeys : function(e){ + if(!(e.ctrlKey || e.metaKey)) return; + e.stopPropagation(); + e.preventDefault(); + const S_KEY = 83; + const P_KEY = 80; + if(e.keyCode == S_KEY) this.save(); + if(e.keyCode == P_KEY) window.open(`/print/${this.props.brew.shareId}?dialog=true`, '_blank').focus(); }, handleSplitMove : function(){ diff --git a/client/homebrew/pages/hijackPrint.js b/client/homebrew/pages/hijackPrint.js index 144a1fc47..e19f5fb94 100644 --- a/client/homebrew/pages/hijackPrint.js +++ b/client/homebrew/pages/hijackPrint.js @@ -1,3 +1,5 @@ +//TODO: Depricate + module.exports = function(shareId){ return function(event){ event = event || window.event; diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index b2a9f634e..d8a2bd470 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -35,7 +35,22 @@ const NewPage = React.createClass({ text : storage }) } + document.addEventListener('keydown', this.handleControlKeys); }, + componentWillUnmount: function() { + document.removeEventListener('keydown', this.handleControlKeys); + }, + + handleControlKeys : function(e){ + if(!(e.ctrlKey || e.metaKey)) return; + e.stopPropagation(); + e.preventDefault(); + const S_KEY = 83; + const P_KEY = 80; + if(e.keyCode == S_KEY) this.save(); + if(e.keyCode == P_KEY) this.print(); + }, + handleSplitMove : function(){ this.refs.editor.update(); }, @@ -54,7 +69,7 @@ const NewPage = React.createClass({ localStorage.setItem(KEY, text); }, - handleSave : function(){ + save : function(){ this.setState({ isSaving : true }); @@ -85,19 +100,19 @@ const NewPage = React.createClass({ save... }else{ - return + return save } }, - handlePrintClick : function(){ + print : function(){ localStorage.setItem('print', this.state.text); window.open('/print?dialog=true&local=print','_blank'); }, renderLocalPrintButton : function(){ - return + return get PDF }, From d400c37b6d6a6017f7f937498617190398bfeee1 Mon Sep 17 00:00:00 2001 From: Scott Tolksdorf Date: Mon, 14 Nov 2016 23:03:58 -0500 Subject: [PATCH 06/17] Updated style to navbar --- client/homebrew/editor/editor.less | 31 ++++++++++++++++--- client/homebrew/pages/newPage/newPage.jsx | 3 -- client/homebrew/pages/sharePage/sharePage.jsx | 30 +++++++++++------- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index 377c71607..611f44d76 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -3,11 +3,12 @@ position : relative; width : 100%; .snippetBar{ - display : flex; - padding : 5px; + @height : 25px; + position : relative; + height : @height; background-color : #ddd; - align-items : center; .snippetGroup{ + /* .animate(background-color); margin : 0px 8px; padding : 3px; @@ -16,8 +17,26 @@ &:hover, &.selected{ background-color : #999; } + */ + display : inline-block; + height : @height; + padding : 0px 5px; + cursor : pointer; + font-size : 0.6em; + font-weight : 800; + line-height : @height; + text-transform : uppercase; + border-right : 1px solid black; + i{ + vertical-align : middle; + margin-right : 3px; + font-size : 1.2em; + } + &:hover, &.selected{ + background-color : #999; + } .text{ - line-height : 20px; + line-height : @height; .groupName{ margin-left : 6px; font-size : 10px; @@ -31,8 +50,10 @@ .dropdown{ position : absolute; visibility : hidden; + top : 100%; z-index : 1000; - padding : 5px; + padding : 0px; + margin-left: -5px; background-color : #ddd; .snippet{ .animate(background-color); diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index d8a2bd470..14ab83b30 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -26,8 +26,6 @@ const NewPage = React.createClass({ errors : [] }; }, - - componentDidMount: function() { const storage = localStorage.getItem(KEY); if(storage){ @@ -80,7 +78,6 @@ const NewPage = React.createClass({ text : this.state.text }) .end((err, res)=>{ - if(err){ this.setState({ isSaving : false diff --git a/client/homebrew/pages/sharePage/sharePage.jsx b/client/homebrew/pages/sharePage/sharePage.jsx index ebe2f54d0..3add2b35c 100644 --- a/client/homebrew/pages/sharePage/sharePage.jsx +++ b/client/homebrew/pages/sharePage/sharePage.jsx @@ -1,17 +1,16 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); +const React = require('react'); +const _ = require('lodash'); +const cx = require('classnames'); -var Nav = require('naturalcrit/nav/nav.jsx'); -var Navbar = require('../../navbar/navbar.jsx'); -var PrintLink = require('../../navbar/print.navitem.jsx'); -var RecentlyViewed = require('../../navbar/recent.navitem.jsx').viewed; +const Nav = require('naturalcrit/nav/nav.jsx'); +const Navbar = require('../../navbar/navbar.jsx'); +const PrintLink = require('../../navbar/print.navitem.jsx'); +const RecentlyViewed = require('../../navbar/recent.navitem.jsx').viewed; -var BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); +const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); -var HijackPrint = require('../hijackPrint.js'); -var SharePage = React.createClass({ +const SharePage = React.createClass({ getDefaultProps: function() { return { ver : '0.0.0', @@ -27,10 +26,17 @@ var SharePage = React.createClass({ }, componentDidMount: function() { - document.onkeydown = HijackPrint(this.props.brew.shareId); + document.addEventListener('keydown', this.handleControlKeys); }, componentWillUnmount: function() { - document.onkeydown = function(){}; + document.removeEventListener('keydown', this.handleControlKeys); + }, + handleControlKeys : function(e){ + if(!(e.ctrlKey || e.metaKey)) return; + e.stopPropagation(); + e.preventDefault(); + const P_KEY = 80; + if(e.keyCode == P_KEY) window.open(`/print/${this.props.brew.shareId}?dialog=true`, '_blank').focus(); }, render : function(){ From ccdb6a3cbdff173833ece3f3693194ebee674e6c Mon Sep 17 00:00:00 2001 From: Scott Tolksdorf Date: Mon, 14 Nov 2016 23:09:26 -0500 Subject: [PATCH 07/17] Removing refernces to ver from pages --- changelog.md | 5 +++++ client/homebrew/pages/editPage/editPage.jsx | 3 +-- client/homebrew/pages/newPage/newPage.jsx | 2 +- client/homebrew/pages/sharePage/sharePage.jsx | 3 +-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index fd5400322..25e52f39f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,10 @@ # changelog +### Monday, 14/11/2016 +- Updated snippet bar style +- You can now print from a new page without saving +- Added the ability to use ctrl+p and ctrl+s to print and save respectively. + ### Monday, 07/11/2016 - Added final touches to the html validator and updating the rest of the branch - If anyone finds issues with the new HTML validator, please let me know. I hope this will bring a more consistent feel to Homebrewery rendering. diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 27cacddf8..a321cd83a 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -26,7 +26,6 @@ const SAVE_TIMEOUT = 3000; var EditPage = React.createClass({ getDefaultProps: function() { return { - ver : '0.0.0', id : null, brew : { title : '', @@ -193,7 +192,7 @@ var EditPage = React.createClass({ } }, renderNavbar : function(){ - return + return diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 14ab83b30..47e5f9562 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -115,7 +115,7 @@ const NewPage = React.createClass({ }, renderNavbar : function(){ - return + return diff --git a/client/homebrew/pages/sharePage/sharePage.jsx b/client/homebrew/pages/sharePage/sharePage.jsx index 3add2b35c..e849de1b4 100644 --- a/client/homebrew/pages/sharePage/sharePage.jsx +++ b/client/homebrew/pages/sharePage/sharePage.jsx @@ -13,7 +13,6 @@ const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); const SharePage = React.createClass({ getDefaultProps: function() { return { - ver : '0.0.0', brew : { title : '', text : '', @@ -41,7 +40,7 @@ const SharePage = React.createClass({ render : function(){ return
- + {this.props.brew.title} From e61bf22788e7001e926369d1ff8c7c906373f525 Mon Sep 17 00:00:00 2001 From: Scott Tolksdorf Date: Wed, 23 Nov 2016 14:47:28 -0500 Subject: [PATCH 08/17] Added in metadata editor --- client/homebrew/editor/editor.jsx | 105 ++++++----------- client/homebrew/editor/editor.less | 72 +----------- .../editor/metadataEditor/metadataEditor.jsx | 106 ++++++++++++++++++ .../editor/metadataEditor/metadataEditor.less | 63 +++++++++++ .../homebrew/editor/snippetbar/snippetbar.jsx | 91 +++++++++++++++ .../editor/snippetbar/snippetbar.less | 72 ++++++++++++ .../snippets/classfeature.gen.js | 0 .../snippets/classtable.gen.js | 0 .../snippets/coverpage.gen.js | 0 .../snippets/fullclass.gen.js | 0 .../{ => snippetbar}/snippets/magic.gen.js | 0 .../snippets/monsterblock.gen.js | 0 .../{ => snippetbar}/snippets/snippets.js | 0 client/homebrew/homebrew.less | 3 + client/homebrew/pages/editPage/editPage.jsx | 88 ++++++++------- client/homebrew/pages/editPage/editPage.less | 2 +- client/homebrew/pages/newPage/newPage.jsx | 29 +++-- server/homebrew.model.js | 5 + shared/naturalcrit/styles/core.less | 38 ++++++- 19 files changed, 483 insertions(+), 191 deletions(-) create mode 100644 client/homebrew/editor/metadataEditor/metadataEditor.jsx create mode 100644 client/homebrew/editor/metadataEditor/metadataEditor.less create mode 100644 client/homebrew/editor/snippetbar/snippetbar.jsx create mode 100644 client/homebrew/editor/snippetbar/snippetbar.less rename client/homebrew/editor/{ => snippetbar}/snippets/classfeature.gen.js (100%) rename client/homebrew/editor/{ => snippetbar}/snippets/classtable.gen.js (100%) rename client/homebrew/editor/{ => snippetbar}/snippets/coverpage.gen.js (100%) rename client/homebrew/editor/{ => snippetbar}/snippets/fullclass.gen.js (100%) rename client/homebrew/editor/{ => snippetbar}/snippets/magic.gen.js (100%) rename client/homebrew/editor/{ => snippetbar}/snippets/monsterblock.gen.js (100%) rename client/homebrew/editor/{ => snippetbar}/snippets/snippets.js (100%) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index d79ef4a98..6b15eaec1 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -1,25 +1,31 @@ -var React = require('react'); -var _ = require('lodash'); -var cx = require('classnames'); +const React = require('react'); +const _ = require('lodash'); +const cx = require('classnames'); -var CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx'); -var Snippets = require('./snippets/snippets.js'); +const CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx'); +const SnippetBar = require('./snippetbar/snippetbar.jsx'); +const MetadataEditor = require('./MetadataEditor/MetadataEditor.jsx'); -var splice = function(str, index, inject){ +const splice = function(str, index, inject){ return str.slice(0, index) + inject + str.slice(index); }; -var execute = function(val){ - if(_.isFunction(val)) return val(); - return val; -} +const SNIPPETBAR_HEIGHT = 25; -var Editor = React.createClass({ +const Editor = React.createClass({ getDefaultProps: function() { return { - value : "", - onChange : function(){} + value : '', + onChange : ()=>{}, + + metadata : {}, + onMetadataChange : ()=>{} + }; + }, + getInitialState: function() { + return { + showMetadataEditor: false }; }, cursorPosition : { @@ -27,7 +33,6 @@ var Editor = React.createClass({ ch : 0 }, - componentDidMount: function() { this.updateEditorSize(); window.addEventListener("resize", this.updateEditorSize); @@ -37,8 +42,8 @@ var Editor = React.createClass({ }, updateEditorSize : function() { - var paneHeight = this.refs.main.parentNode.clientHeight; - paneHeight -= this.refs.snippetBar.clientHeight + 1; + let paneHeight = this.refs.main.parentNode.clientHeight; + paneHeight -= SNIPPETBAR_HEIGHT + 1; this.refs.codeEditor.codeMirror.setSize(null, paneHeight); }, @@ -48,38 +53,37 @@ var Editor = React.createClass({ handleCursorActivty : function(curpos){ this.cursorPosition = curpos; }, - - handleSnippetClick : function(injectText){ - var lines = this.props.value.split('\n'); + handleInject : function(injectText){ + const lines = this.props.value.split('\n'); lines[this.cursorPosition.line] = splice(lines[this.cursorPosition.line], this.cursorPosition.ch, injectText); this.handleTextChange(lines.join('\n')); this.refs.codeEditor.setCursorPosition(this.cursorPosition.line, this.cursorPosition.ch + injectText.length); }, + handgleToggle : function(){ + this.setState({ + showMetadataEditor : !this.state.showMetadataEditor + }) + }, //Called when there are changes to the editor's dimensions update : function(){ this.refs.codeEditor.updateSize(); }, - renderSnippetGroups : function(){ - return _.map(Snippets, (snippetGroup)=>{ - return - }) + renderMetadataEditor : function(){ + if(!this.state.showMetadataEditor) return; + return }, render : function(){ return(
-
- {this.renderSnippetGroups()} -
+ + {this.renderMetadataEditor()} { - return
- - {snippet.name} -
- }) - }, - - render : function(){ - return
-
- - {this.props.groupName} -
-
- {this.renderSnippets()} -
-
- }, - -}); \ No newline at end of file diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index 611f44d76..8678fd189 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -2,76 +2,10 @@ .editor{ position : relative; width : 100%; - .snippetBar{ - @height : 25px; - position : relative; - height : @height; - background-color : #ddd; - .snippetGroup{ - /* - .animate(background-color); - margin : 0px 8px; - padding : 3px; - font-size : 13px; - border-radius : 5px; - &:hover, &.selected{ - background-color : #999; - } - */ - display : inline-block; - height : @height; - padding : 0px 5px; - cursor : pointer; - font-size : 0.6em; - font-weight : 800; - line-height : @height; - text-transform : uppercase; - border-right : 1px solid black; - i{ - vertical-align : middle; - margin-right : 3px; - font-size : 1.2em; - } - &:hover, &.selected{ - background-color : #999; - } - .text{ - line-height : @height; - .groupName{ - margin-left : 6px; - font-size : 10px; - } - } - &:hover{ - .dropdown{ - visibility : visible; - } - } - .dropdown{ - position : absolute; - visibility : hidden; - top : 100%; - z-index : 1000; - padding : 0px; - margin-left: -5px; - background-color : #ddd; - .snippet{ - .animate(background-color); - padding : 10px; - cursor : pointer; - font-size : 10px; - i{ - margin-right: 8px; - font-size : 13px; - } - &:hover{ - background-color : #999; - } - } - } - } - } + .codeEditor{ height : 100%; } + + } \ No newline at end of file diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx new file mode 100644 index 000000000..4fd395f6b --- /dev/null +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -0,0 +1,106 @@ +const React = require('react'); +const _ = require('lodash'); +const cx = require('classnames'); + +const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder'] + +const MetadataEditor = React.createClass({ + getDefaultProps: function() { + return { + metadata: { + title : '', + description : '', + tags : '', + published : false, + authors : [], + systems : [] + }, + onChange : ()=>{} + }; + }, + + handleFieldChange : function(name, e){ + this.props.onChange(_.merge({}, this.props.metadata, { + [name] : e.target.value + })) + }, + handleSystem : function(system, e){ + if(e.target.checked){ + this.props.metadata.systems.push(system); + }else{ + this.props.metadata.systems = _.without(this.props.metadata.systems, system); + } + this.props.onChange(this.props.metadata); + }, + handlePublish : function(val){ + this.props.onChange(_.merge({}, this.props.metadata, { + published : val + })); + }, + + renderSystems : function(){ + return _.map(SYSTEMS, (val)=>{ + return + }); + }, + + renderPublish : function(){ + if(this.props.metadata.published){ + return + }else{ + return + } + }, + + render : function(){ + return
+ +
+ + +
+
+ +