mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-28 22:12:39 +00:00
Merge branch 'master' of https://github.com/naturalcrit/homebrewery into nav-fixes
This commit is contained in:
@@ -20,7 +20,7 @@ const PAGE_HEIGHT = 1056;
|
||||
|
||||
const INITIAL_CONTENT = dedent`
|
||||
<!DOCTYPE html><html><head>
|
||||
<link href="//use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet" />
|
||||
<link href="//use.fontawesome.com/releases/v6.5.1/css/all.css" rel="stylesheet" />
|
||||
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
|
||||
<link href='/homebrew/bundle.css' rel='stylesheet' />
|
||||
<base target=_blank>
|
||||
|
||||
@@ -160,21 +160,21 @@ const Editor = createClass({
|
||||
}
|
||||
}
|
||||
|
||||
// Superscript
|
||||
if(line.includes('\^')) {
|
||||
const regex = /\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^/g;
|
||||
let match;
|
||||
while ((match = regex.exec(line)) != null) {
|
||||
codeMirror.markText({ line: lineNumber, ch: line.indexOf(match[1]) - 1 }, { line: lineNumber, ch: line.indexOf(match[1]) + match[1].length + 1 }, { className: 'superscript' });
|
||||
}
|
||||
}
|
||||
|
||||
// Subscript
|
||||
if(line.includes('^^')) {
|
||||
const regex = /\^\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^\^/g;
|
||||
let match;
|
||||
while ((match = regex.exec(line)) != null) {
|
||||
codeMirror.markText({ line: lineNumber, ch: line.indexOf(match[1]) - 2 }, { line: lineNumber, ch: line.indexOf(match[1]) + match[1].length + 2 }, { className: 'subscript' });
|
||||
// Subscript & Superscript
|
||||
if(line.includes('^')) {
|
||||
let startIndex = line.indexOf('^');
|
||||
const superRegex = /\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^/gy;
|
||||
const subRegex = /\^\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^\^/gy;
|
||||
|
||||
while (startIndex >= 0) {
|
||||
superRegex.lastIndex = subRegex.lastIndex = startIndex;
|
||||
let isSuper = false;
|
||||
let match = subRegex.exec(line) || superRegex.exec(line);
|
||||
if (match) {
|
||||
isSuper = !subRegex.lastIndex;
|
||||
codeMirror.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: isSuper ? 'superscript' : 'subscript' });
|
||||
}
|
||||
startIndex = line.indexOf('^', Math.max(startIndex + 1, subRegex.lastIndex, superRegex.lastIndex));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "naturalcrit/styles/colors.less";
|
||||
@import 'naturalcrit/styles/colors.less';
|
||||
|
||||
@navbarHeight : 28px;
|
||||
|
||||
@@ -29,324 +29,317 @@
|
||||
z-index : 2;
|
||||
display : flex;
|
||||
justify-content : space-between;
|
||||
.navSection {
|
||||
}
|
||||
.navSection {
|
||||
display : flex;
|
||||
align-items : center;
|
||||
&:last-child .navItem { border-left : 1px solid #666666; }
|
||||
}
|
||||
// "NaturalCrit" logo
|
||||
.navLogo {
|
||||
display : block;
|
||||
margin-top : 0px;
|
||||
margin-right : 8px;
|
||||
margin-left : 8px;
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
&:hover {
|
||||
.name { color : @orange; }
|
||||
svg { fill : @orange; }
|
||||
}
|
||||
svg {
|
||||
height : 13px;
|
||||
margin-right : 0.2em;
|
||||
cursor : pointer;
|
||||
fill : white;
|
||||
}
|
||||
span.name {
|
||||
font-family : 'CodeLight';
|
||||
font-size : 15px;
|
||||
span.crit { font-family : 'CodeBold'; }
|
||||
small {
|
||||
font-family : 'Open Sans';
|
||||
font-size : 0.3em;
|
||||
font-weight : 800;
|
||||
text-transform : uppercase;
|
||||
}
|
||||
}
|
||||
}
|
||||
.navItem {
|
||||
#backgroundColorsHover;
|
||||
.animate(background-color);
|
||||
padding : 8px 12px;
|
||||
font-size : 10px;
|
||||
font-weight : 800;
|
||||
line-height : 13px;
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
text-transform : uppercase;
|
||||
cursor : pointer;
|
||||
background-color : #333333;
|
||||
i {
|
||||
float : right;
|
||||
margin-left : 5px;
|
||||
font-size : 13px;
|
||||
}
|
||||
&.patreon {
|
||||
border-right : 1px solid #666666;
|
||||
border-left : 1px solid #666666;
|
||||
&:hover i { color : red; }
|
||||
i {
|
||||
color : pink;
|
||||
.animate(color);
|
||||
animation-name : pinkColoring;
|
||||
animation-duration : 2s;
|
||||
}
|
||||
}
|
||||
&.editTitle { // this is not needed at all currently - you used to be able to edit the title via the navbar.
|
||||
padding : 2px 12px;
|
||||
input {
|
||||
width : 250px;
|
||||
padding : 2px;
|
||||
margin : 0;
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
font-size : 12px;
|
||||
font-weight : 800;
|
||||
color : white;
|
||||
text-align : center;
|
||||
background-color : transparent;
|
||||
border : 1px solid @blue;
|
||||
outline : none;
|
||||
}
|
||||
.charCount {
|
||||
display : inline-block;
|
||||
margin-left : 8px;
|
||||
color : #666666;
|
||||
text-align : right;
|
||||
vertical-align : bottom;
|
||||
&.max { color : @red; }
|
||||
}
|
||||
}
|
||||
&.brewTitle {
|
||||
flex-grow : 1;
|
||||
font-size : 12px;
|
||||
font-weight : 800;
|
||||
color : white;
|
||||
text-align : center;
|
||||
text-transform : initial;
|
||||
background-color : transparent;
|
||||
}
|
||||
// "The Homebrewery" logo
|
||||
&.homebrewLogo {
|
||||
.animate(color);
|
||||
font-family : 'CodeBold';
|
||||
font-size : 12px;
|
||||
color : white;
|
||||
div {
|
||||
margin-top : 2px;
|
||||
margin-bottom : -2px;
|
||||
}
|
||||
&:hover { color : @blue; }
|
||||
}
|
||||
&.metadata {
|
||||
position : relative;
|
||||
display : flex;
|
||||
flex-grow : 1;
|
||||
align-items : center;
|
||||
// "NaturalCrit" logo
|
||||
.navLogo {
|
||||
display : block;
|
||||
margin-top : 0px;
|
||||
margin-right : 8px;
|
||||
margin-left : 8px;
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
&:hover {
|
||||
.name { color : @orange; }
|
||||
svg { fill : @orange; }
|
||||
height : 100%;
|
||||
padding : 0;
|
||||
i { margin-right : 10px;}
|
||||
.window {
|
||||
position : absolute;
|
||||
bottom : 0;
|
||||
left : 50%;
|
||||
z-index : -1;
|
||||
display : flex;
|
||||
flex-flow : row wrap;
|
||||
align-content : baseline;
|
||||
justify-content : flex-start;
|
||||
width : 440px;
|
||||
max-height : ~'calc(100vh - 28px)';
|
||||
padding : 0 10px 5px;
|
||||
margin : 0 auto;
|
||||
background-color : #333333;
|
||||
border : 3px solid #444444;
|
||||
border-top : unset;
|
||||
border-radius : 0 0 5px 5px;
|
||||
box-shadow : inset 0 7px 9px -7px #111111;
|
||||
transition : transform 0.4s, opacity 0.4s;
|
||||
&.active {
|
||||
opacity : 1;
|
||||
transform : translateX(-50%) translateY(100%);
|
||||
}
|
||||
svg {
|
||||
height : 13px;
|
||||
margin-right : 0.2em;
|
||||
cursor : pointer;
|
||||
fill : white;
|
||||
&.inactive {
|
||||
opacity : 0;
|
||||
transform : translateX(-50%) translateY(0%);
|
||||
}
|
||||
span.name {
|
||||
font-family : 'CodeLight';
|
||||
font-size : 15px;
|
||||
span.crit { font-family : 'CodeBold'; }
|
||||
small {
|
||||
font-family : 'Open Sans';
|
||||
font-size : 0.3em;
|
||||
font-weight : 800;
|
||||
text-transform : uppercase;
|
||||
.row {
|
||||
display : flex;
|
||||
flex-flow : row wrap;
|
||||
width : 100%;
|
||||
h4 {
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
flex-basis : 20%;
|
||||
flex-grow : 1;
|
||||
min-width : 76px;
|
||||
padding : 5px 0;
|
||||
color : #BBBBBB;
|
||||
text-align : center;
|
||||
}
|
||||
p {
|
||||
flex-basis : 80%;
|
||||
flex-grow : 1;
|
||||
padding : 5px 0;
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
font-size : 10px;
|
||||
font-weight : normal;
|
||||
text-transform : initial;
|
||||
.tag {
|
||||
display : inline-block;
|
||||
padding : 2px;
|
||||
margin : 2px 2px;
|
||||
background-color : #444444;
|
||||
border : 2px solid grey;
|
||||
border-radius : 5px;
|
||||
}
|
||||
a.userPageLink {
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
&:hover { text-decoration : underline; }
|
||||
}
|
||||
}
|
||||
&:nth-of-type(even) { background-color : #555555; }
|
||||
}
|
||||
}
|
||||
&:last-child .navItem { border-left : 1px solid #666666; }
|
||||
}
|
||||
&.warning {
|
||||
position : relative;
|
||||
color : white;
|
||||
background-color : @orange;
|
||||
&:hover > .dropdown { visibility : visible; }
|
||||
.dropdown {
|
||||
position : absolute;
|
||||
top : 28px;
|
||||
left : 0;
|
||||
z-index : 10000;
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
width : 100%;
|
||||
padding : 13px 5px;
|
||||
text-align : center;
|
||||
visibility : hidden;
|
||||
background-color : #333333;
|
||||
}
|
||||
}
|
||||
&.account {
|
||||
min-width : 100px;
|
||||
&.username { text-transform : none;}
|
||||
}
|
||||
}
|
||||
.navDropdownContainer {
|
||||
position : relative;
|
||||
.navDropdown {
|
||||
position : absolute;
|
||||
top : 28px;
|
||||
left : 0px;
|
||||
z-index : 10000;
|
||||
width : 100%;
|
||||
max-height : calc(100vh - 28px);
|
||||
overflow : hidden auto;
|
||||
.navItem {
|
||||
position : relative;
|
||||
display : block;
|
||||
width : 100%;
|
||||
padding : 8px 5px;
|
||||
border : 1px solid #888888;
|
||||
border-bottom : 0;
|
||||
animation-name : glideDropDown;
|
||||
animation-duration : 0.4s;
|
||||
}
|
||||
}
|
||||
&.recent {
|
||||
position : relative;
|
||||
.navDropdown .navItem {
|
||||
#backgroundColorsHover;
|
||||
.animate(background-color);
|
||||
padding : 8px 12px;
|
||||
font-size : 10px;
|
||||
font-weight : 800;
|
||||
line-height : 13px;
|
||||
position : relative;
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
max-height : ~'calc(100vh - 28px)';
|
||||
padding : 8px 5px 13px;
|
||||
overflow : hidden auto;
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
text-transform : uppercase;
|
||||
cursor : pointer;
|
||||
background-color : #333333;
|
||||
i {
|
||||
float : right;
|
||||
margin-left : 5px;
|
||||
font-size : 13px;
|
||||
}
|
||||
&.patreon {
|
||||
border-right : 1px solid #666666;
|
||||
border-left : 1px solid #666666;
|
||||
&:hover i { color : red; }
|
||||
border-top : 1px solid #888888;
|
||||
scrollbar-color : #666666 #333333;
|
||||
scrollbar-width : thin;
|
||||
.clear {
|
||||
position : absolute;
|
||||
top : 50%;
|
||||
right : 0;
|
||||
display : none;
|
||||
width : 20px;
|
||||
height : 100%;
|
||||
background-color : #333333;
|
||||
border-radius : 3px;
|
||||
opacity : 70%;
|
||||
transform : translateY(-50%);
|
||||
&:hover { opacity : 100%; }
|
||||
i {
|
||||
color : pink;
|
||||
.animate(color);
|
||||
animation-name : pinkColoring;
|
||||
animation-duration : 2s;
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
margin : 0;
|
||||
font-size : 10px;
|
||||
text-align : center;
|
||||
}
|
||||
}
|
||||
&.editTitle { // this is not needed at all currently - you used to be able to edit the title via the navbar.
|
||||
padding : 2px 12px;
|
||||
input {
|
||||
width : 250px;
|
||||
padding : 2px;
|
||||
margin : 0;
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
font-size : 12px;
|
||||
font-weight : 800;
|
||||
color : white;
|
||||
text-align : center;
|
||||
background-color : transparent;
|
||||
border : 1px solid @blue;
|
||||
outline : none;
|
||||
}
|
||||
.charCount {
|
||||
display : inline-block;
|
||||
margin-left : 8px;
|
||||
color : #666666;
|
||||
text-align : right;
|
||||
vertical-align : bottom;
|
||||
&.max { color : @red; }
|
||||
&:hover {
|
||||
background-color : @blue;
|
||||
.clear {
|
||||
display : grid;
|
||||
place-content : center;
|
||||
}
|
||||
}
|
||||
&.brewTitle {
|
||||
flex-grow : 1;
|
||||
font-size : 12px;
|
||||
font-weight : 800;
|
||||
color : white;
|
||||
.title {
|
||||
display : inline-block;
|
||||
width : 100%;
|
||||
overflow : hidden auto;
|
||||
text-overflow : ellipsis;
|
||||
white-space : nowrap;
|
||||
}
|
||||
.time {
|
||||
position : absolute;
|
||||
right : 2px;
|
||||
bottom : 2px;
|
||||
font-size : 0.7em;
|
||||
color : #888888;
|
||||
}
|
||||
&.header {
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
padding : 5px 0;
|
||||
color : #BBBBBB;
|
||||
text-align : center;
|
||||
text-transform : initial;
|
||||
background-color : transparent;
|
||||
}
|
||||
// "The Homebrewery" logo
|
||||
&.homebrewLogo {
|
||||
.animate(color);
|
||||
font-family : 'CodeBold';
|
||||
font-size : 12px;
|
||||
color : white;
|
||||
div {
|
||||
margin-top : 2px;
|
||||
margin-bottom : -2px;
|
||||
}
|
||||
&:hover { color : @blue; }
|
||||
}
|
||||
&.metadata {
|
||||
position : relative;
|
||||
display : flex;
|
||||
flex-grow : 1;
|
||||
align-items : center;
|
||||
height : 100%;
|
||||
padding : 0;
|
||||
i { margin-right : 10px;}
|
||||
.window {
|
||||
position : absolute;
|
||||
bottom : 0;
|
||||
left : 50%;
|
||||
z-index : -1;
|
||||
display : flex;
|
||||
flex-flow : row wrap;
|
||||
align-content : baseline;
|
||||
justify-content : flex-start;
|
||||
width : 440px;
|
||||
max-height : ~"calc(100vh - 28px)";
|
||||
padding : 0 10px 5px;
|
||||
margin : 0 auto;
|
||||
background-color : #333333;
|
||||
border : 3px solid #444444;
|
||||
border-top : unset;
|
||||
border-radius : 0 0 5px 5px;
|
||||
box-shadow : inset 0 7px 9px -7px #111111;
|
||||
transition : transform 0.4s, opacity 0.4s;
|
||||
&.active {
|
||||
opacity : 1;
|
||||
transform : translateX(-50%) translateY(100%);
|
||||
}
|
||||
&.inactive {
|
||||
opacity : 0;
|
||||
transform : translateX(-50%) translateY(0%);
|
||||
}
|
||||
.row {
|
||||
display : flex;
|
||||
flex-flow : row wrap;
|
||||
width : 100%;
|
||||
h4 {
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
flex-basis : 20%;
|
||||
flex-grow : 1;
|
||||
min-width : 76px;
|
||||
padding : 5px 0;
|
||||
color : #BBBBBB;
|
||||
text-align : center;
|
||||
}
|
||||
p {
|
||||
flex-basis : 80%;
|
||||
flex-grow : 1;
|
||||
padding : 5px 0;
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
font-size : 10px;
|
||||
font-weight : normal;
|
||||
text-transform : initial;
|
||||
.tag {
|
||||
display : inline-block;
|
||||
padding : 2px;
|
||||
margin : 2px 2px;
|
||||
background-color : #444444;
|
||||
border : 2px solid grey;
|
||||
border-radius : 5px;
|
||||
}
|
||||
a.userPageLink {
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
&:hover { text-decoration : underline; }
|
||||
}
|
||||
}
|
||||
&:nth-of-type(even) { background-color : #555555; }
|
||||
}
|
||||
}
|
||||
}
|
||||
&.warning {
|
||||
position : relative;
|
||||
color : white;
|
||||
background-color : @orange;
|
||||
&:hover > .dropdown { visibility : visible; }
|
||||
.dropdown {
|
||||
position : absolute;
|
||||
top : 28px;
|
||||
left : 0;
|
||||
z-index : 10000;
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
width : 100%;
|
||||
padding : 13px 5px;
|
||||
text-align : center;
|
||||
visibility : hidden;
|
||||
background-color : #333333;
|
||||
}
|
||||
}
|
||||
&.account {
|
||||
min-width : 100px;
|
||||
&.username { text-transform : none;}
|
||||
}
|
||||
}
|
||||
.navDropdownContainer {
|
||||
position : relative;
|
||||
min-width: 120px;
|
||||
.navDropdown {
|
||||
position : absolute;
|
||||
top : 28px;
|
||||
left : 0px;
|
||||
z-index : 10000;
|
||||
width : 100%;
|
||||
max-height : calc(100vh - 28px);
|
||||
overflow : hidden auto;
|
||||
.navItem {
|
||||
position : relative;
|
||||
display : flex;
|
||||
justify-content : space-between;
|
||||
align-items : center;
|
||||
width : 100%;
|
||||
border : 1px solid #888888;
|
||||
border-bottom : 0;
|
||||
animation-name : glideDropDown;
|
||||
animation-duration : 0.4s;
|
||||
}
|
||||
}
|
||||
&.recent {
|
||||
position : relative;
|
||||
.navDropdown .navItem {
|
||||
#backgroundColorsHover;
|
||||
.animate(background-color);
|
||||
position : relative;
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
max-height : ~"calc(100vh - 28px)"; // I don't think is correct syntax, but leaving it in for now... (Gazook89)
|
||||
padding : 8px 5px 13px;
|
||||
overflow : hidden auto;
|
||||
color : white;
|
||||
text-decoration : none;
|
||||
background-color : #333333;
|
||||
border-top : 1px solid #888888;
|
||||
scrollbar-color : #666666 #333333;
|
||||
scrollbar-width : thin;
|
||||
.clear {
|
||||
position : absolute;
|
||||
top : 50%;
|
||||
right : 0;
|
||||
display : none;
|
||||
width : 20px;
|
||||
height : 100%;
|
||||
background-color : #333333;
|
||||
border-radius : 3px;
|
||||
opacity : 70%;
|
||||
transform : translateY(-50%);
|
||||
&:hover { opacity : 100%; }
|
||||
i {
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
margin : 0;
|
||||
font-size : 10px;
|
||||
text-align : center;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color : @blue;
|
||||
.clear {
|
||||
display : grid;
|
||||
place-content : center;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
display : inline-block;
|
||||
width : 100%;
|
||||
overflow : hidden auto;
|
||||
text-overflow : ellipsis;
|
||||
white-space : nowrap;
|
||||
}
|
||||
.time {
|
||||
position : absolute;
|
||||
right : 2px;
|
||||
bottom : 2px;
|
||||
font-size : 0.7em;
|
||||
color : #888888;
|
||||
}
|
||||
&.header {
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
padding : 5px 0;
|
||||
color : #BBBBBB;
|
||||
text-align : center;
|
||||
background-color : #333333;
|
||||
border-top : 1px solid #888888;
|
||||
&:nth-of-type(1) { background-color : darken(@teal, 20%); }
|
||||
&:nth-of-type(2) { background-color : darken(@purple, 30%); }
|
||||
}
|
||||
}
|
||||
background-color : #333333;
|
||||
border-top : 1px solid #888888;
|
||||
&:nth-of-type(1) { background-color : darken(@teal, 20%); }
|
||||
&:nth-of-type(2) { background-color : darken(@purple, 30%); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this should likely be refactored into .navDropdownContainer
|
||||
.save-menu {
|
||||
.dropdown { z-index : 1000; }
|
||||
.navItem i.fa-power-off {
|
||||
color : red;
|
||||
&.active {
|
||||
color : rgb(0, 182, 52);
|
||||
filter : drop-shadow(0 0 2px rgba(0, 182, 52, 0.765));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// this should likely be refactored into .navDropdownContainer
|
||||
.save-menu {
|
||||
.dropdown { z-index : 1000; }
|
||||
.navItem i.fa-power-off {
|
||||
color : red;
|
||||
&.active {
|
||||
color : rgb(0, 182, 52);
|
||||
filter : drop-shadow(0 0 2px rgba(0, 182, 52, 0.765));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,64 @@
|
||||
const React = require('react');
|
||||
const _ = require('lodash');
|
||||
const Nav = require('naturalcrit/nav/nav.jsx');
|
||||
const { splitTextStyleAndMetadata } = require('../../../shared/helpers.js'); // Importing the function from helpers.js
|
||||
|
||||
module.exports = function(props){
|
||||
return <Nav.item
|
||||
href='/new'
|
||||
newTab={true}
|
||||
color='purple'
|
||||
icon='fas fa-plus-square'>
|
||||
new
|
||||
</Nav.item>;
|
||||
const BREWKEY = 'homebrewery-new';
|
||||
const STYLEKEY = 'homebrewery-new-style';
|
||||
const METAKEY = 'homebrewery-new-meta';
|
||||
|
||||
const NewBrew = () => {
|
||||
const handleFileChange = (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const fileContent = e.target.result;
|
||||
const newBrew = {
|
||||
text: fileContent,
|
||||
style: ''
|
||||
};
|
||||
if(fileContent.startsWith('```metadata')) {
|
||||
splitTextStyleAndMetadata(newBrew); // Modify newBrew directly
|
||||
localStorage.setItem(BREWKEY, newBrew.text);
|
||||
localStorage.setItem(STYLEKEY, newBrew.style);
|
||||
localStorage.setItem(METAKEY, JSON.stringify(_.pick(newBrew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])));
|
||||
window.location.href = '/new';
|
||||
} else {
|
||||
alert('This file is invalid, please, enter a valid file');
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Nav.dropdown>
|
||||
<Nav.item
|
||||
className='new'
|
||||
color='purple'
|
||||
icon='fa-solid fa-plus-square'>
|
||||
new
|
||||
</Nav.item>
|
||||
<Nav.item
|
||||
className='fromBlank'
|
||||
href='/new'
|
||||
newTab={true}
|
||||
color='purple'
|
||||
icon='fa-solid fa-file'>
|
||||
from blank
|
||||
</Nav.item>
|
||||
|
||||
<Nav.item
|
||||
className='fromFile'
|
||||
color='purple'
|
||||
icon='fa-solid fa-upload'
|
||||
onClick={() => { document.getElementById('uploadTxt').click(); }}>
|
||||
<input id="uploadTxt" className='newFromLocal' type="file" onChange={handleFileChange} style={{ display: 'none' }} />
|
||||
from file
|
||||
</Nav.item>
|
||||
</Nav.dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = NewBrew;
|
||||
|
||||
@@ -12,7 +12,7 @@ const template = async function(name, title='', props = {}){
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, height=device-height, interactive-widget=resizes-visual" />
|
||||
<link href="//use.fontawesome.com/releases/v5.15.1/css/all.css" rel="stylesheet" />
|
||||
<link href="//use.fontawesome.com/releases/v6.5.1/css/all.css" rel="stylesheet" />
|
||||
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
|
||||
<link href=${`/${name}/bundle.css`} rel='stylesheet' />
|
||||
<link rel="icon" href="/assets/favicon.ico" type="image/x-icon" />
|
||||
|
||||
922
package-lock.json
generated
922
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@@ -80,9 +80,9 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/plugin-transform-runtime": "^7.23.9",
|
||||
"@babel/preset-env": "^7.23.9",
|
||||
"@babel/core": "^7.24.0",
|
||||
"@babel/plugin-transform-runtime": "^7.24.0",
|
||||
"@babel/preset-env": "^7.24.0",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"@googleapis/drive": "^8.7.0",
|
||||
"body-parser": "^1.20.2",
|
||||
@@ -92,7 +92,7 @@
|
||||
"create-react-class": "^15.7.0",
|
||||
"dedent-tabs": "^0.10.3",
|
||||
"expr-eval": "^2.0.2",
|
||||
"express": "^4.18.2",
|
||||
"express": "^4.18.3",
|
||||
"express-async-handler": "^1.2.0",
|
||||
"express-static-gzip": "2.1.7",
|
||||
"fs-extra": "11.2.0",
|
||||
@@ -106,13 +106,13 @@
|
||||
"marked-smartypants-lite": "^1.0.2",
|
||||
"markedLegacy": "npm:marked@^0.3.19",
|
||||
"moment": "^2.30.1",
|
||||
"mongoose": "^8.2.0",
|
||||
"mongoose": "^8.2.1",
|
||||
"nanoid": "3.3.4",
|
||||
"nconf": "^0.12.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-frame-component": "^4.1.3",
|
||||
"react-router-dom": "6.22.1",
|
||||
"react-router-dom": "6.22.2",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"superagent": "^8.1.2",
|
||||
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
||||
@@ -120,7 +120,7 @@
|
||||
"devDependencies": {
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-jest": "^27.9.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react": "^7.34.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-expect-message": "^1.1.3",
|
||||
"postcss-less": "^6.0.0",
|
||||
|
||||
@@ -17,21 +17,8 @@ const asyncHandler = require('express-async-handler');
|
||||
|
||||
const { DEFAULT_BREW } = require('./brewDefaults.js');
|
||||
|
||||
const splitTextStyleAndMetadata = (brew)=>{
|
||||
brew.text = brew.text.replaceAll('\r\n', '\n');
|
||||
if(brew.text.startsWith('```metadata')) {
|
||||
const index = brew.text.indexOf('```\n\n');
|
||||
const metadataSection = brew.text.slice(12, index - 1);
|
||||
const metadata = yaml.load(metadataSection);
|
||||
Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang']));
|
||||
brew.text = brew.text.slice(index + 5);
|
||||
}
|
||||
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);
|
||||
}
|
||||
};
|
||||
const { splitTextStyleAndMetadata } = require('../shared/helpers.js');
|
||||
|
||||
|
||||
const sanitizeBrew = (brew, accessType)=>{
|
||||
brew._id = undefined;
|
||||
|
||||
22
shared/helpers.js
Normal file
22
shared/helpers.js
Normal file
@@ -0,0 +1,22 @@
|
||||
const _ = require('lodash');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
const splitTextStyleAndMetadata = (brew) => {
|
||||
brew.text = brew.text.replaceAll('\r\n', '\n');
|
||||
if (brew.text.startsWith('```metadata')) {
|
||||
const index = brew.text.indexOf('```\n\n');
|
||||
const metadataSection = brew.text.slice(12, index - 1);
|
||||
const metadata = yaml.load(metadataSection);
|
||||
Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang']));
|
||||
brew.text = brew.text.slice(index + 5);
|
||||
}
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
splitTextStyleAndMetadata
|
||||
};
|
||||
@@ -78,7 +78,7 @@ module.exports = function(props){
|
||||
|
||||
return dedent`
|
||||
{{toc,wide
|
||||
# Table Of Contents
|
||||
# Contents
|
||||
|
||||
${markdown}
|
||||
}}
|
||||
|
||||
@@ -402,15 +402,9 @@
|
||||
}
|
||||
}
|
||||
.pageNumber {
|
||||
position : absolute;
|
||||
right : 2px;
|
||||
bottom : 22px;
|
||||
width : 50px;
|
||||
font-size : 0.9em;
|
||||
color : var(--HB_Color_Footnotes);
|
||||
text-align : center;
|
||||
text-indent : 0;
|
||||
&.auto::after { content : counter(phb-page-numbers); }
|
||||
}
|
||||
.footnote {
|
||||
position : absolute;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
}
|
||||
|
||||
@page { margin : 0; }
|
||||
body { counter-reset : phb-page-numbers; }
|
||||
body { counter-reset : page-numbers; }
|
||||
* { -webkit-print-color-adjust : exact; }
|
||||
|
||||
//*****************************
|
||||
@@ -47,7 +47,7 @@ body { counter-reset : phb-page-numbers; }
|
||||
height : 279.4mm;
|
||||
padding : 1.4cm 1.9cm 1.7cm;
|
||||
overflow : hidden;
|
||||
counter-increment : phb-page-numbers;
|
||||
counter-increment : page-numbers;
|
||||
background-color : var(--HB_Color_Background);
|
||||
text-rendering : optimizeLegibility;
|
||||
contain : size;
|
||||
@@ -166,7 +166,6 @@ body { counter-reset : phb-page-numbers; }
|
||||
margin : 0;
|
||||
font-size : 120px;
|
||||
text-transform : uppercase;
|
||||
mix-blend-mode : overlay;
|
||||
opacity : 30%;
|
||||
transform : rotate(-45deg);
|
||||
p { margin-bottom : none; }
|
||||
@@ -460,3 +459,22 @@ body { counter-reset : phb-page-numbers; }
|
||||
.homebreweryIcon.red { background-color : red; }
|
||||
.homebreweryIcon.gold { background-image : linear-gradient(to top left, brown 22.5%, gold 40%, white 60%, gold 67.5%, brown 82.5%); }
|
||||
}
|
||||
|
||||
//*****************************
|
||||
//* Page Number
|
||||
//*****************************/
|
||||
.page {
|
||||
.pageNumber {
|
||||
position : absolute;
|
||||
right : 30px;
|
||||
bottom : 30px;
|
||||
width : 50px;
|
||||
font-size : 0.9em;
|
||||
text-align : center;
|
||||
&.auto::after { content : counter(page-numbers); }
|
||||
}
|
||||
|
||||
&:nth-child(even) {
|
||||
.pageNumber { left : 30px; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,17 +374,9 @@
|
||||
}
|
||||
.pageNumber{
|
||||
font-family : FrederickaTheGreat;
|
||||
position : absolute;
|
||||
right : 3cm;
|
||||
bottom : 1.25cm;
|
||||
width : 50px;
|
||||
font-size : 0.9em;
|
||||
color : var(--HB_Color_HeaderText);
|
||||
text-align : center;
|
||||
text-indent : 0;
|
||||
&.auto::after {
|
||||
content : counter(phb-page-numbers);
|
||||
}
|
||||
}
|
||||
.footnote{
|
||||
position : absolute;
|
||||
|
||||
Reference in New Issue
Block a user