mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-25 16:15:53 +00:00
Merge commit '2661e2cf' into PRODUCTION
This commit is contained in:
21
changelog.md
21
changelog.md
@@ -6,6 +6,27 @@ h5 {
|
||||
|
||||
# changelog
|
||||
|
||||
### Saturday, 28/6/2021 - v2.13.1
|
||||
|
||||
- Fixed the issue with new brews not saving!
|
||||
|
||||
### Saturday, 26/6/2021 - v2.13.0
|
||||
|
||||
- "Share to Reddit" button now works with Google brews
|
||||
- Downloading or viewing the source of your brew will now show the contents of the Style tab at the top of the document in a backtick code fence like this:
|
||||
|
||||
\`\`\`css
|
||||
|
||||
myStyle {color: black}
|
||||
|
||||
\`\`\`
|
||||
|
||||
##### G-Ambatte :
|
||||
- New **Download**, **View**, and **Clone to New** buttons in the "Source" dropdown on the Share page.
|
||||
- Pasting your brew into a "New" page and saving will transfer any CSS in the code fence to the Style tab.
|
||||
- Unsaved work in the New page Style tab is now cached to your browser storage if you navigate away.
|
||||
|
||||
|
||||
### Thursday, 10/6/2021 - v2.12.0
|
||||
|
||||
- New "style" tab to better organize custom CSS in preparation for new themes and sharable styles.
|
||||
|
||||
@@ -23,7 +23,7 @@ const NotificationPopup = createClass({
|
||||
psa : function(){
|
||||
return <li key='psa'>
|
||||
<em>Google Drive Integration!</em> <br />
|
||||
We have added Google Drive integration to the Homebrewery! <a target='_blank' href='http://naturalcrit.com/login'>Sign in</a> with
|
||||
We have added Google Drive integration to the Homebrewery! <a target='_blank' href='https://www.naturalcrit.com/login'>Sign in</a> with
|
||||
your Google account to link it with your Homebrewery profile. A new button in the Edit page will let you transfer your file to your personal
|
||||
Google Drive storage, and Google will keep a backup of each version! No more lost work surprises!
|
||||
<br /><br />
|
||||
|
||||
@@ -3,17 +3,26 @@ const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const cx = require('classnames');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx');
|
||||
const SnippetBar = require('./snippetbar/snippetbar.jsx');
|
||||
const MetadataEditor = require('./metadataEditor/metadataEditor.jsx');
|
||||
|
||||
const SNIPPETBAR_HEIGHT = 25;
|
||||
const DEFAULT_STYLE_TEXT = dedent`
|
||||
/*=======--- Example CSS styling ---=======*/
|
||||
/* Any CSS here will apply to your document! */
|
||||
|
||||
.myExampleClass {
|
||||
color: black;
|
||||
}`;
|
||||
|
||||
const splice = function(str, index, inject){
|
||||
return str.slice(0, index) + inject + str.slice(index);
|
||||
};
|
||||
|
||||
const SNIPPETBAR_HEIGHT = 25;
|
||||
|
||||
|
||||
const Editor = createClass({
|
||||
getDefaultProps : function() {
|
||||
@@ -176,7 +185,7 @@ const Editor = createClass({
|
||||
return <CodeEditor key='style'
|
||||
ref='codeEditor'
|
||||
language='css'
|
||||
value={this.props.brew.style}
|
||||
value={this.props.brew.style ?? DEFAULT_STYLE_TEXT}
|
||||
onChange={this.props.onStyleChange} />;
|
||||
}
|
||||
if(this.isMeta()){
|
||||
|
||||
@@ -67,10 +67,12 @@ const MetadataEditor = createClass({
|
||||
|
||||
getRedditLink : function(){
|
||||
const meta = this.props.metadata;
|
||||
|
||||
const shareLink = (meta.googleId || '') + meta.shareId;
|
||||
const title = `${meta.title} [${meta.systems.join(' ')}]`;
|
||||
const text = `Hey guys! I've been working on this homebrew. I'd love your feedback. Check it out.
|
||||
|
||||
**[Homebrewery Link](http://homebrewery.naturalcrit.com/share/${meta.shareId})**`;
|
||||
**[Homebrewery Link](https://homebrewery.naturalcrit.com/share/${shareLink})**`;
|
||||
|
||||
return `https://www.reddit.com/r/UnearthedArcana/submit?title=${encodeURIComponent(title)}&text=${encodeURIComponent(text)}`;
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@import 'naturalcrit/styles/core.less';
|
||||
.homebrew{
|
||||
height : 100%;
|
||||
.page{
|
||||
.sitePage{
|
||||
display : flex;
|
||||
height : 100%;
|
||||
background-color : @steel;
|
||||
|
||||
@@ -25,7 +25,7 @@ const Account = createClass({
|
||||
</Nav.item>;
|
||||
}
|
||||
|
||||
return <Nav.item href={`http://naturalcrit.com/login?redirect=${this.state.url}`} color='teal' icon='fas fa-sign-in-alt'>
|
||||
return <Nav.item href={`https://www.naturalcrit.com/login?redirect=${this.state.url}`} color='teal' icon='fas fa-sign-in-alt'>
|
||||
login
|
||||
</Nav.item>;
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ const EditPage = createClass({
|
||||
You must be signed in to a Google account to transfer
|
||||
between the homebrewery and Google Drive!
|
||||
<a target='_blank' rel='noopener noreferrer'
|
||||
href={`http://naturalcrit.com/login?redirect=${this.state.url}`}>
|
||||
href={`https://www.naturalcrit.com/login?redirect=${this.state.url}`}>
|
||||
<div className='confirm'>
|
||||
Sign In
|
||||
</div>
|
||||
@@ -332,7 +332,7 @@ const EditPage = createClass({
|
||||
You must be signed in to a Google account
|
||||
to save this to<br />Google Drive!<br />
|
||||
<a target='_blank' rel='noopener noreferrer'
|
||||
href={`http://naturalcrit.com/login?redirect=${this.state.url}`}>
|
||||
href={`https://www.naturalcrit.com/login?redirect=${this.state.url}`}>
|
||||
<div className='confirm'>
|
||||
Sign In
|
||||
</div>
|
||||
@@ -349,7 +349,7 @@ const EditPage = createClass({
|
||||
<div className='errorContainer'>
|
||||
Looks like there was a problem saving. <br />
|
||||
Report the issue <a target='_blank' rel='noopener noreferrer'
|
||||
href={`https://github.com/naturalcrt/naturalcrit/issues/new?body=${encodeURIComponent(errMsg)}`}>
|
||||
href={`https://github.com/naturalcrit/homebrewery/issues/new?body=${encodeURIComponent(errMsg)}`}>
|
||||
here
|
||||
</a>.
|
||||
</div>
|
||||
@@ -406,7 +406,7 @@ const EditPage = createClass({
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return <div className='editPage page'>
|
||||
return <div className='editPage sitePage'>
|
||||
<Meta name='robots' content='noindex, nofollow' />
|
||||
{this.renderNavbar()}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const ErrorPage = createClass({
|
||||
text : '# Oops \n We could not find a brew with that id. **Sorry!**',
|
||||
|
||||
render : function(){
|
||||
return <div className='errorPage page'>
|
||||
return <div className='errorPage sitePage'>
|
||||
<Navbar ver={this.props.ver}>
|
||||
<Nav.section>
|
||||
<Nav.item className='errorTitle'>
|
||||
|
||||
@@ -72,7 +72,7 @@ const HomePage = createClass({
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return <div className='homePage page'>
|
||||
return <div className='homePage sitePage'>
|
||||
<Meta name='google-site-verification' content='NwnAQSSJZzAT7N-p5MY6ydQ7Njm67dtbu73ZSyE5Fy4' />
|
||||
{this.renderNavbar()}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
|
||||
require('./newPage.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const request = require('superagent');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
|
||||
@@ -17,20 +17,15 @@ const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
|
||||
const Editor = require('../../editor/editor.jsx');
|
||||
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
|
||||
|
||||
const KEY = 'homebrewery-new';
|
||||
const BREWKEY = 'homebrewery-new';
|
||||
const STYLEKEY = 'homebrewery-new-style';
|
||||
|
||||
|
||||
const NewPage = createClass({
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
brew : {
|
||||
text : '',
|
||||
style : dedent`
|
||||
/*=======--- Example CSS styling ---=======*/
|
||||
/* Any CSS here will apply to your document! */
|
||||
|
||||
.myExampleClass {
|
||||
color: black;
|
||||
}`,
|
||||
text : '',
|
||||
shareId : null,
|
||||
editId : null,
|
||||
createdAt : null,
|
||||
@@ -51,7 +46,6 @@ const NewPage = createClass({
|
||||
return {
|
||||
brew : {
|
||||
text : this.props.brew.text || '',
|
||||
style : this.props.brew.style || '',
|
||||
gDrive : false,
|
||||
title : this.props.brew.title || '',
|
||||
description : this.props.brew.description || '',
|
||||
@@ -70,10 +64,15 @@ const NewPage = createClass({
|
||||
},
|
||||
|
||||
componentDidMount : function() {
|
||||
const storage = localStorage.getItem(KEY);
|
||||
if(!this.props.brew.text && storage){
|
||||
const brewStorage = localStorage.getItem(BREWKEY);
|
||||
const styleStorage = localStorage.getItem(STYLEKEY);
|
||||
|
||||
if(!this.props.brew.text || !this.props.brew.style){
|
||||
this.setState({
|
||||
brew : { text: storage }
|
||||
brew : {
|
||||
text : this.props.brew.text || (brewStorage ?? ''),
|
||||
style : this.props.brew.style || (styleStorage ?? undefined)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -112,13 +111,14 @@ const NewPage = createClass({
|
||||
brew : _.merge({}, prevState.brew, { text: text }),
|
||||
htmlErrors : htmlErrors
|
||||
}));
|
||||
localStorage.setItem(KEY, text);
|
||||
localStorage.setItem(BREWKEY, text);
|
||||
},
|
||||
|
||||
handleStyleChange : function(style){
|
||||
this.setState((prevState)=>({
|
||||
brew : _.merge({}, prevState.brew, { style: style }),
|
||||
}));
|
||||
localStorage.setItem(STYLEKEY, style);
|
||||
},
|
||||
|
||||
handleMetaChange : function(metadata){
|
||||
@@ -135,10 +135,18 @@ const NewPage = createClass({
|
||||
|
||||
console.log('saving new brew');
|
||||
|
||||
let brew = this.state.brew;
|
||||
// Split out CSS to Style if CSS codefence exists
|
||||
if(brew.text.startsWith('```css') && brew.text.indexOf('```\n\n') > 0) {
|
||||
const index = brew.text.indexOf('```\n\n');
|
||||
brew.style = `${brew.style ? `${brew.style}\n` : ''}${brew.text.slice(7, index - 1)}`;
|
||||
brew.text = brew.text.slice(index + 5);
|
||||
};
|
||||
|
||||
if(this.state.saveGoogle) {
|
||||
const res = await request
|
||||
.post('/api/newGoogle/')
|
||||
.send(this.state.brew)
|
||||
.send(brew)
|
||||
.catch((err)=>{
|
||||
console.log(err.status === 401
|
||||
? 'Not signed in!'
|
||||
@@ -147,12 +155,13 @@ const NewPage = createClass({
|
||||
return;
|
||||
});
|
||||
|
||||
const brew = res.body;
|
||||
localStorage.removeItem(KEY);
|
||||
brew = res.body;
|
||||
localStorage.removeItem(BREWKEY);
|
||||
localStorage.removeItem(STYLEKEY);
|
||||
window.location = `/edit/${brew.googleId}${brew.editId}`;
|
||||
} else {
|
||||
request.post('/api')
|
||||
.send(this.state.brew)
|
||||
.send(brew)
|
||||
.end((err, res)=>{
|
||||
if(err){
|
||||
this.setState({
|
||||
@@ -161,8 +170,9 @@ const NewPage = createClass({
|
||||
return;
|
||||
}
|
||||
window.onbeforeunload = function(){};
|
||||
const brew = res.body;
|
||||
localStorage.removeItem(KEY);
|
||||
brew = res.body;
|
||||
localStorage.removeItem(BREWKEY);
|
||||
localStorage.removeItem(STYLEKEY);
|
||||
window.location = `/edit/${brew.editId}`;
|
||||
});
|
||||
}
|
||||
@@ -181,7 +191,7 @@ const NewPage = createClass({
|
||||
},
|
||||
|
||||
print : function(){
|
||||
localStorage.setItem('print', this.state.brew.text);
|
||||
localStorage.setItem('print', `<style>\n${this.state.brew.style}\n</style>\n\n${this.state.brew.text}`);
|
||||
window.open('/print?dialog=true&local=print', '_blank');
|
||||
},
|
||||
|
||||
@@ -209,7 +219,7 @@ const NewPage = createClass({
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return <div className='newPage page'>
|
||||
return <div className='newPage sitePage'>
|
||||
{this.renderNavbar()}
|
||||
<div className='content'>
|
||||
<SplitPane onDragFinish={this.handleSplitMove} ref='pane'>
|
||||
|
||||
@@ -39,7 +39,7 @@ const PrintPage = createClass({
|
||||
if(this.props.brew.renderer == 'legacy') {
|
||||
return _.map(this.state.brewText.split('\\page'), (page, index)=>{
|
||||
return <div
|
||||
className='phb'
|
||||
className='phb page'
|
||||
id={`p${index + 1}`}
|
||||
dangerouslySetInnerHTML={{ __html: MarkdownLegacy.render(page) }}
|
||||
key={index} />;
|
||||
@@ -47,7 +47,7 @@ const PrintPage = createClass({
|
||||
} else {
|
||||
return _.map(this.state.brewText.split(/^\\page/gm), (page, index)=>{
|
||||
return <div
|
||||
className='phb3'
|
||||
className='phb3 page'
|
||||
id={`p${index + 1}`}
|
||||
dangerouslySetInnerHTML={{ __html: Markdown.render(page) }}
|
||||
key={index} />;
|
||||
|
||||
@@ -29,6 +29,12 @@ const SharePage = createClass({
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState : function() {
|
||||
return {
|
||||
showDropdown : false
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount : function() {
|
||||
document.addEventListener('keydown', this.handleControlKeys);
|
||||
},
|
||||
@@ -51,8 +57,30 @@ const SharePage = createClass({
|
||||
this.props.brew.shareId;
|
||||
},
|
||||
|
||||
handleDropdown : function(show){
|
||||
this.setState({
|
||||
showDropdown : show
|
||||
});
|
||||
},
|
||||
|
||||
renderDropdown : function(){
|
||||
if(!this.state.showDropdown) return null;
|
||||
|
||||
return <div className='dropdown'>
|
||||
<a href={`/source/${this.processShareId()}`} className='item'>
|
||||
view
|
||||
</a>
|
||||
<a href={`/download/${this.processShareId()}`} className='item'>
|
||||
download
|
||||
</a>
|
||||
<a href={`/new/${this.processShareId()}`} className='item'>
|
||||
clone to new
|
||||
</a>
|
||||
</div>;
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return <div className='sharePage page'>
|
||||
return <div className='sharePage sitePage'>
|
||||
<Meta name='robots' content='noindex, nofollow' />
|
||||
<Navbar>
|
||||
<Nav.section>
|
||||
@@ -61,11 +89,11 @@ const SharePage = createClass({
|
||||
|
||||
<Nav.section>
|
||||
<PrintLink shareId={this.processShareId()} />
|
||||
<Nav.item href={`/source/${this.processShareId()}`} color='teal' icon='fas fa-code'>
|
||||
<Nav.item icon='fas fa-code' color='red' className='source'
|
||||
onMouseEnter={()=>this.handleDropdown(true)}
|
||||
onMouseLeave={()=>this.handleDropdown(false)}>
|
||||
source
|
||||
</Nav.item>
|
||||
<Nav.item href={`/download/${this.processShareId()}`} color='red' icon='fas fa-download'>
|
||||
download
|
||||
{this.renderDropdown()}
|
||||
</Nav.item>
|
||||
<RecentNavItem brew={this.props.brew} storageKey='view' />
|
||||
<Account />
|
||||
|
||||
@@ -2,4 +2,49 @@
|
||||
.content{
|
||||
overflow-y : hidden;
|
||||
}
|
||||
.source.navItem{
|
||||
position : relative;
|
||||
.dropdown{
|
||||
position : absolute;
|
||||
top : 28px;
|
||||
left : 0px;
|
||||
z-index : 10000;
|
||||
width : 100%;
|
||||
h4{
|
||||
display : block;
|
||||
box-sizing : border-box;
|
||||
padding : 5px 0px;
|
||||
background-color : #333;
|
||||
font-size : 0.8em;
|
||||
color : #bbb;
|
||||
text-align : center;
|
||||
border-top : 1px solid #888;
|
||||
&:nth-of-type(1){ background-color: darken(@teal, 20%); }
|
||||
&:nth-of-type(2){ background-color: darken(@purple, 30%); }
|
||||
}
|
||||
.item{
|
||||
.animate(background-color);
|
||||
position : relative;
|
||||
display : block;
|
||||
width : 100%;
|
||||
vertical-align : middle;
|
||||
padding : 13px 5px;
|
||||
box-sizing : border-box;
|
||||
background-color : #333;
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
border-top : 1px solid #888;
|
||||
&:hover{
|
||||
background-color : @blue;
|
||||
}
|
||||
.title{
|
||||
display : inline-block;
|
||||
overflow : hidden;
|
||||
width : 100%;
|
||||
text-overflow : ellipsis;
|
||||
white-space : nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ const UserPage = createClass({
|
||||
render : function(){
|
||||
const brews = this.getSortedBrews();
|
||||
|
||||
return <div className='userPage page'>
|
||||
return <div className='userPage sitePage'>
|
||||
<Navbar>
|
||||
<Nav.section>
|
||||
<NewBrew />
|
||||
|
||||
4238
package-lock.json
generated
4238
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "homebrewery",
|
||||
"description": "Create authentic looking D&D homebrews using only markdown",
|
||||
"version": "2.12.0",
|
||||
"version": "2.13.1",
|
||||
"engines": {
|
||||
"node": "14.15.x"
|
||||
},
|
||||
@@ -40,32 +40,32 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/core": "^7.14.6",
|
||||
"@babel/plugin-transform-runtime": "^7.14.5",
|
||||
"@babel/preset-env": "^7.14.4",
|
||||
"@babel/preset-react": "^7.13.13",
|
||||
"@babel/preset-env": "^7.14.7",
|
||||
"@babel/preset-react": "^7.14.5",
|
||||
"body-parser": "^1.19.0",
|
||||
"classnames": "^2.3.1",
|
||||
"codemirror": "^5.61.1",
|
||||
"codemirror": "^5.62.0",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"create-react-class": "^15.7.0",
|
||||
"dedent-tabs": "^0.9.0",
|
||||
"express": "^4.17.1",
|
||||
"express-async-handler": "^1.1.4",
|
||||
"express-static-gzip": "2.1.1",
|
||||
"fs-extra": "9.1.0",
|
||||
"googleapis": "75.0.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"googleapis": "78.0.0",
|
||||
"jwt-simple": "^0.5.6",
|
||||
"less": "^3.13.1",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "2.0.6",
|
||||
"marked": "2.1.3",
|
||||
"markedLegacy": "npm:marked@^0.3.19",
|
||||
"moment": "^2.29.1",
|
||||
"mongoose": "^5.12.12",
|
||||
"mongoose": "^5.12.15",
|
||||
"nanoid": "3.1.23",
|
||||
"nconf": "^0.11.2",
|
||||
"nconf": "^0.11.3",
|
||||
"prop-types": "15.7.2",
|
||||
"query-string": "7.0.0",
|
||||
"query-string": "7.0.1",
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.14.0",
|
||||
"react-frame-component": "4.1.3",
|
||||
@@ -75,8 +75,8 @@
|
||||
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.27.0",
|
||||
"eslint-plugin-react": "^7.23.2",
|
||||
"eslint": "^7.29.0",
|
||||
"eslint-plugin-react": "^7.24.0",
|
||||
"pico-check": "^2.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
23
server.js
23
server.js
@@ -9,11 +9,12 @@ const GoogleActions = require('./server/googleActions.js');
|
||||
const serveCompressedStaticAssets = require('./server/static-assets.mv.js');
|
||||
const sanitizeFilename = require('sanitize-filename');
|
||||
const asyncHandler = require('express-async-handler');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const brewAccessTypes = ['edit', 'share', 'raw'];
|
||||
|
||||
//Get the brew object from the HB database or Google Drive
|
||||
const getBrewFromId = asyncHandler(async (id, accessType)=>{
|
||||
if(accessType !== 'edit' && accessType !== 'share')
|
||||
if(!brewAccessTypes.includes(accessType))
|
||||
throw ('Invalid Access Type when getting brew');
|
||||
let brew;
|
||||
if(id.length > 12) {
|
||||
@@ -22,23 +23,19 @@ const getBrewFromId = asyncHandler(async (id, accessType)=>{
|
||||
brew = await GoogleActions.readFileMetadata(config.get('google_api_key'), googleId, id, accessType);
|
||||
} else {
|
||||
brew = await HomebrewModel.get(accessType == 'edit' ? { editId: id } : { shareId: id });
|
||||
brew = brew.toObject();
|
||||
brew = brew.toObject(); // Convert MongoDB object to standard Javascript Object
|
||||
}
|
||||
|
||||
brew = sanitizeBrew(brew, accessType === 'edit' ? false : true);
|
||||
//Split brew.text into text and style
|
||||
//unless the Access Type is RAW, in which case return immediately
|
||||
if(accessType == 'raw') {
|
||||
return brew;
|
||||
}
|
||||
if(brew.text.startsWith('```css')) {
|
||||
const index = brew.text.indexOf('```\n\n');
|
||||
brew.style = brew.text.slice(7, index - 1);
|
||||
brew.text = brew.text.slice(index + 5);
|
||||
} else {
|
||||
brew.style = dedent`
|
||||
/*=======--- Example CSS styling ---=======*/
|
||||
/* Any CSS here will apply to your document! */
|
||||
|
||||
.myExampleClass {
|
||||
color: black;
|
||||
}`;
|
||||
}
|
||||
return brew;
|
||||
});
|
||||
@@ -110,7 +107,7 @@ app.get('/robots.txt', (req, res)=>{
|
||||
|
||||
//Source page
|
||||
app.get('/source/:id', asyncHandler(async (req, res)=>{
|
||||
const brew = await getBrewFromId(req.params.id, 'share');
|
||||
const brew = await getBrewFromId(req.params.id, 'raw');
|
||||
|
||||
const replaceStrings = { '&': '&', '<': '<', '>': '>' };
|
||||
let text = brew.text;
|
||||
@@ -123,7 +120,7 @@ app.get('/source/:id', asyncHandler(async (req, res)=>{
|
||||
|
||||
//Download brew source page
|
||||
app.get('/download/:id', asyncHandler(async (req, res)=>{
|
||||
const brew = await getBrewFromId(req.params.id, 'share');
|
||||
const brew = await getBrewFromId(req.params.id, 'raw');
|
||||
const prefix = 'HB - ';
|
||||
|
||||
let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', '');
|
||||
|
||||
@@ -20,10 +20,12 @@ const getGoodBrewTitle = (text)=>{
|
||||
};
|
||||
|
||||
const mergeBrewText = (text, style)=>{
|
||||
text = `\`\`\`css\n` +
|
||||
`${style}\n` +
|
||||
`\`\`\`\n\n` +
|
||||
`${text}`;
|
||||
if(typeof style !== 'undefined') {
|
||||
text = `\`\`\`css\n` +
|
||||
`${style}\n` +
|
||||
`\`\`\`\n\n` +
|
||||
`${text}`;
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ HomebrewSchema.statics.getByUser = function(username, allowAccess=false){
|
||||
if(allowAccess){
|
||||
delete query.published;
|
||||
}
|
||||
Homebrew.find(query, (err, brews)=>{
|
||||
Homebrew.find(query).lean().exec((err, brews)=>{ //lean() converts results to JSObjects
|
||||
if(err) return reject('Can not find brew');
|
||||
return resolve(brews);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ const Nav = {
|
||||
}
|
||||
}),
|
||||
logo : function(){
|
||||
return <a className='navLogo' href='http://naturalcrit.com'>
|
||||
return <a className='navLogo' href='https://www.naturalcrit.com'>
|
||||
<NaturalCritIcon />
|
||||
<span className='name'>
|
||||
Natural<span className='crit'>Crit</span>
|
||||
|
||||
Reference in New Issue
Block a user