diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less
index c1cda38c3..ae11c1e7e 100644
--- a/client/homebrew/navbar/navbar.less
+++ b/client/homebrew/navbar/navbar.less
@@ -25,12 +25,11 @@
.homebrew nav {
background-color : #333333;
- .navContent {
- position : relative;
- z-index : 2;
- display : flex;
- justify-content : space-between;
- }
+ position : relative;
+ z-index : 2;
+ display : flex;
+ justify-content : space-between;
+
.navSection {
display : flex;
align-items : center;
diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx
index 7fcee9e0c..744e187a6 100644
--- a/client/homebrew/pages/editPage/editPage.jsx
+++ b/client/homebrew/pages/editPage/editPage.jsx
@@ -429,42 +429,40 @@ const EditPage = createClass({
{this.renderNavbar()}
-
- {this.props.brew.lock && }
-
-
-
-
-
+ {this.props.brew.lock && }
+
+
+
+
;
}
});
diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx
index ac3be81df..3b21c7398 100644
--- a/client/homebrew/pages/homePage/homePage.jsx
+++ b/client/homebrew/pages/homePage/homePage.jsx
@@ -100,35 +100,31 @@ const HomePage = createClass({
return
{this.renderNavbar()}
-
-
-
-
-
-
-
-
+
+
+
+
Save current
diff --git a/client/homebrew/pages/homePage/welcome_msg.md b/client/homebrew/pages/homePage/welcome_msg.md
index c7d46149e..49d1918f0 100644
--- a/client/homebrew/pages/homePage/welcome_msg.md
+++ b/client/homebrew/pages/homePage/welcome_msg.md
@@ -91,13 +91,6 @@ If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](
\page
-
-
-
-
-
-
-
## Markdown+
The Homebrewery aims to make homebrewing as simple as possible, providing a live editor with Markdown syntax that is more human-readable and faster to write with than raw HTML.
diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx
index c147cd474..cb8d5b3ae 100644
--- a/client/homebrew/pages/newPage/newPage.jsx
+++ b/client/homebrew/pages/newPage/newPage.jsx
@@ -223,39 +223,37 @@ const NewPage = createClass({
render : function(){
return
{this.renderNavbar()}
-
-
-
-
-
-
+
+
+
+
;
}
});
diff --git a/client/homebrew/pages/sharePage/sharePage.less b/client/homebrew/pages/sharePage/sharePage.less
index 83e784c49..754108506 100644
--- a/client/homebrew/pages/sharePage/sharePage.less
+++ b/client/homebrew/pages/sharePage/sharePage.less
@@ -1,5 +1,5 @@
.sharePage{
- .navContent .navSection.titleSection {
+ nav .navSection.titleSection {
flex-grow: 1;
justify-content: center;
}
diff --git a/client/homebrew/pages/userPage/userPage.jsx b/client/homebrew/pages/userPage/userPage.jsx
index d6fe25b30..f6fae639d 100644
--- a/client/homebrew/pages/userPage/userPage.jsx
+++ b/client/homebrew/pages/userPage/userPage.jsx
@@ -1,12 +1,11 @@
const React = require('react');
-const createClass = require('create-react-class');
-const _ = require('lodash');
+const { useState } = React;
+const _ = require('lodash');
const ListPage = require('../basePages/listPage/listPage.jsx');
const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
-
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const Account = require('../../navbar/account.navitem.jsx');
const NewBrew = require('../../navbar/newbrew.navitem.jsx');
@@ -14,69 +13,48 @@ const HelpNavItem = require('../../navbar/help.navitem.jsx');
const ErrorNavItem = require('../../navbar/error-navitem.jsx');
const VaultNavitem = require('../../navbar/vault.navitem.jsx');
-const UserPage = createClass({
- displayName : 'UserPage',
- getDefaultProps : function() {
- return {
- username : '',
- brews : [],
- query : '',
- error : null
- };
- },
- getInitialState : function() {
- const usernameWithS = this.props.username + (this.props.username.endsWith('s') ? `’` : `’s`);
+const UserPage = (props)=>{
+ props = {
+ username : '',
+ brews : [],
+ query : '',
+ ...props
+ };
- const brews = _.groupBy(this.props.brews, (brew)=>{
- return (brew.published ? 'published' : 'private');
- });
+ const [error, setError] = useState(null);
- const brewCollection = [
- {
- title : `${usernameWithS} published brews`,
- class : 'published',
- brews : brews.published
- }
- ];
- if(this.props.username == global.account?.username){
- brewCollection.push(
- {
- title : `${usernameWithS} unpublished brews`,
- class : 'unpublished',
- brews : brews.private
- }
- );
- }
+ const usernameWithS = props.username + (props.username.endsWith('s') ? `’` : `’s`);
+ const groupedBrews = _.groupBy(props.brews, (brew)=>brew.published ? 'published' : 'private');
- return {
- brewCollection : brewCollection
- };
- },
- errorReported : function(error) {
- this.setState({
- error
- });
- },
+ const brewCollection = [
+ {
+ title : `${usernameWithS} published brews`,
+ class : 'published',
+ brews : groupedBrews.published || []
+ },
+ ...(props.username === global.account?.username ? [{
+ title : `${usernameWithS} unpublished brews`,
+ class : 'unpublished',
+ brews : groupedBrews.private || []
+ }] : [])
+ ];
- navItems : function() {
- return
+ const navItems = (
+
- {this.state.error ?
- :
- null
- }
+ {error && ( )}
-
+
- ;
- },
+
+ );
- render : function(){
- return
;
- }
-});
+ return (
+
setError(err)} />
+ );
+};
module.exports = UserPage;
diff --git a/client/homebrew/pages/vaultPage/vaultPage.jsx b/client/homebrew/pages/vaultPage/vaultPage.jsx
index a51039345..55b0cb370 100644
--- a/client/homebrew/pages/vaultPage/vaultPage.jsx
+++ b/client/homebrew/pages/vaultPage/vaultPage.jsx
@@ -415,16 +415,13 @@ const VaultPage = (props)=>{
{renderNavItems()}
-
-
- {renderForm()}
-
-
- {renderSortBar()}
- {renderFoundBrews()}
-
-
-
+
+ {renderForm()}
+
+ {renderSortBar()}
+ {renderFoundBrews()}
+
+
);
};
diff --git a/package-lock.json b/package-lock.json
index 43f8936f8..3cdad9cb9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,9 +10,9 @@
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
- "@babel/core": "^7.25.9",
+ "@babel/core": "^7.26.0",
"@babel/plugin-transform-runtime": "^7.25.9",
- "@babel/preset-env": "^7.25.9",
+ "@babel/preset-env": "^7.26.0",
"@babel/preset-react": "^7.25.9",
"@googleapis/drive": "^8.14.0",
"body-parser": "^1.20.2",
@@ -39,7 +39,7 @@
"marked-smartypants-lite": "^1.0.2",
"markedLegacy": "npm:marked@^0.3.19",
"moment": "^2.30.1",
- "mongoose": "^8.7.2",
+ "mongoose": "^8.7.3",
"nanoid": "3.3.4",
"nconf": "^0.12.1",
"react": "^18.3.1",
@@ -83,11 +83,12 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.9.tgz",
- "integrity": "sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.0.tgz",
+ "integrity": "sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==",
"dependencies": {
- "@babel/highlight": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
@@ -95,28 +96,28 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.9.tgz",
- "integrity": "sha512-yD+hEuJ/+wAJ4Ox2/rpNv5HIuPG82x3ZlQvYVn8iYCprdxzE7P1udpGF1jyjQVBU4dgznN+k2h103vxZ7NdPyw==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.0.tgz",
+ "integrity": "sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.9.tgz",
- "integrity": "sha512-WYvQviPw+Qyib0v92AwNIrdLISTp7RfDkM7bPqBvpbnhY4wq8HvHBZREVdYDXk98C8BkOIVnHAY3yvj7AVISxQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz",
+ "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.25.9",
- "@babel/generator": "^7.25.9",
+ "@babel/code-frame": "^7.26.0",
+ "@babel/generator": "^7.26.0",
"@babel/helper-compilation-targets": "^7.25.9",
- "@babel/helper-module-transforms": "^7.25.9",
- "@babel/helpers": "^7.25.9",
- "@babel/parser": "^7.25.9",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.0",
+ "@babel/parser": "^7.26.0",
"@babel/template": "^7.25.9",
"@babel/traverse": "^7.25.9",
- "@babel/types": "^7.25.9",
+ "@babel/types": "^7.26.0",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -132,11 +133,12 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.9.tgz",
- "integrity": "sha512-omlUGkr5EaoIJrhLf9CJ0TvjBRpd9+AXRG//0GEQ9THSo8wPiTlbpy1/Ow8ZTrbXpjd9FHXfbFQx32I04ht0FA==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.0.tgz",
+ "integrity": "sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==",
"dependencies": {
- "@babel/types": "^7.25.9",
+ "@babel/parser": "^7.26.0",
+ "@babel/types": "^7.26.0",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
@@ -260,12 +262,11 @@
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.9.tgz",
- "integrity": "sha512-TvLZY/F3+GvdRYFZFyxMvnsKi+4oJdgZzU3BoGN9Uc2d9C6zfNwJcKKhjqLAhK8i46mv93jsO74fDh3ih6rpHA==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
"dependencies": {
"@babel/helper-module-imports": "^7.25.9",
- "@babel/helper-simple-access": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9",
"@babel/traverse": "^7.25.9"
},
@@ -389,37 +390,23 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.9.tgz",
- "integrity": "sha512-oKWp3+usOJSzDZOucZUAMayhPz/xVjzymyDzUN8dk0Wd3RWMlGLXi07UCQ/CgQVb8LvXx3XBajJH4XGgkt7H7g==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
+ "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
"dependencies": {
"@babel/template": "^7.25.9",
- "@babel/types": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz",
- "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.25.9",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "@babel/types": "^7.26.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.9.tgz",
- "integrity": "sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==",
+ "version": "7.26.1",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.1.tgz",
+ "integrity": "sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==",
"dependencies": {
- "@babel/types": "^7.25.9"
+ "@babel/types": "^7.26.0"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -554,9 +541,9 @@
}
},
"node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.9.tgz",
- "integrity": "sha512-4GHX5uzr5QMOOuzV0an9MFju4hKlm0OyePl/lHhcsTVae5t/IKVHnb8W67Vr6FuLlk5lPqLB7n7O+K5R46emYg==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
+ "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -568,9 +555,9 @@
}
},
"node_modules/@babel/plugin-syntax-import-attributes": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.9.tgz",
- "integrity": "sha512-u3EN9ub8LyYvgTnrgp8gboElouayiwPdnM7x5tcnW3iSt09/lQYPwMNK40I9IUxo7QOZhAsPHCmmuO7EPdruqg==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+ "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -837,9 +824,9 @@
}
},
"node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.9.tgz",
- "integrity": "sha512-UIf+72C7YJ+PJ685/PpATbCz00XqiFEzHX5iysRwfvNT0Ko+FaXSvRgLytFSp8xUItrG9pFM/KoBBZDrY/cYyg==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
+ "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -1396,6 +1383,21 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
+ "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
"node_modules/@babel/plugin-transform-reserved-words": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
@@ -1560,11 +1562,11 @@
}
},
"node_modules/@babel/preset-env": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.9.tgz",
- "integrity": "sha512-XqDEt+hfsQukahSX9JOBDHhpUHDhj2zGSxoqWQFCMajOSBnbhBdgON/bU/5PkBA1yX5tqW6tTzuIPVsZTQ7h5Q==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz",
+ "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==",
"dependencies": {
- "@babel/compat-data": "^7.25.9",
+ "@babel/compat-data": "^7.26.0",
"@babel/helper-compilation-targets": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/helper-validator-option": "^7.25.9",
@@ -1574,8 +1576,8 @@
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
"@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
- "@babel/plugin-syntax-import-assertions": "^7.25.9",
- "@babel/plugin-syntax-import-attributes": "^7.25.9",
+ "@babel/plugin-syntax-import-assertions": "^7.26.0",
+ "@babel/plugin-syntax-import-attributes": "^7.26.0",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
"@babel/plugin-transform-arrow-functions": "^7.25.9",
"@babel/plugin-transform-async-generator-functions": "^7.25.9",
@@ -1583,7 +1585,7 @@
"@babel/plugin-transform-block-scoped-functions": "^7.25.9",
"@babel/plugin-transform-block-scoping": "^7.25.9",
"@babel/plugin-transform-class-properties": "^7.25.9",
- "@babel/plugin-transform-class-static-block": "^7.25.9",
+ "@babel/plugin-transform-class-static-block": "^7.26.0",
"@babel/plugin-transform-classes": "^7.25.9",
"@babel/plugin-transform-computed-properties": "^7.25.9",
"@babel/plugin-transform-destructuring": "^7.25.9",
@@ -1616,6 +1618,7 @@
"@babel/plugin-transform-private-property-in-object": "^7.25.9",
"@babel/plugin-transform-property-literals": "^7.25.9",
"@babel/plugin-transform-regenerator": "^7.25.9",
+ "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
"@babel/plugin-transform-reserved-words": "^7.25.9",
"@babel/plugin-transform-shorthand-properties": "^7.25.9",
"@babel/plugin-transform-spread": "^7.25.9",
@@ -1724,9 +1727,9 @@
}
},
"node_modules/@babel/types": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.9.tgz",
- "integrity": "sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
+ "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
@@ -3359,17 +3362,6 @@
"node": ">=8"
}
},
- "node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@@ -4457,19 +4449,6 @@
}
]
},
- "node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/char-regex": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
@@ -4622,19 +4601,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
- },
"node_modules/colord": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
@@ -5691,14 +5657,6 @@
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
- "node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "engines": {
- "node": ">=0.8.0"
- }
- },
"node_modules/eslint": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz",
@@ -10652,9 +10610,9 @@
}
},
"node_modules/mongoose": {
- "version": "8.7.2",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.7.2.tgz",
- "integrity": "sha512-Ok4VzMds9p5G3ZSUhmvBm1GdxanbzhS29jpSn02SPj+IXEVFnIdfwAlHHXWkyNscZKlcn8GuMi68FH++jo0flg==",
+ "version": "8.7.3",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.7.3.tgz",
+ "integrity": "sha512-Xl6+dzU5ZpEcDoJ8/AyrIdAwTY099QwpolvV73PIytpK13XqwllLq/9XeVzzLEQgmyvwBVGVgjmMrKbuezxrIA==",
"dependencies": {
"bson": "^6.7.0",
"kareem": "2.6.3",
diff --git a/package.json b/package.json
index 5a3857b73..94d0122ab 100644
--- a/package.json
+++ b/package.json
@@ -86,9 +86,9 @@
]
},
"dependencies": {
- "@babel/core": "^7.25.9",
+ "@babel/core": "^7.26.0",
"@babel/plugin-transform-runtime": "^7.25.9",
- "@babel/preset-env": "^7.25.9",
+ "@babel/preset-env": "^7.26.0",
"@babel/preset-react": "^7.25.9",
"@googleapis/drive": "^8.14.0",
"body-parser": "^1.20.2",
@@ -115,7 +115,7 @@
"marked-smartypants-lite": "^1.0.2",
"markedLegacy": "npm:marked@^0.3.19",
"moment": "^2.30.1",
- "mongoose": "^8.7.2",
+ "mongoose": "^8.7.3",
"nanoid": "3.3.4",
"nconf": "^0.12.1",
"react": "^18.3.1",
diff --git a/shared/naturalcrit/nav/nav.jsx b/shared/naturalcrit/nav/nav.jsx
index a4682aeab..d9b403239 100644
--- a/shared/naturalcrit/nav/nav.jsx
+++ b/shared/naturalcrit/nav/nav.jsx
@@ -12,10 +12,8 @@ const Nav = {
displayName : 'Nav.base',
render : function(){
return
-
{this.props.children}
-
- ;
+ ;
}
}),
logo : function(){
diff --git a/shared/naturalcrit/splitPane/splitPane.jsx b/shared/naturalcrit/splitPane/splitPane.jsx
index 23ae5d321..1500c759f 100644
--- a/shared/naturalcrit/splitPane/splitPane.jsx
+++ b/shared/naturalcrit/splitPane/splitPane.jsx
@@ -1,200 +1,110 @@
require('./splitPane.less');
const React = require('react');
-const createClass = require('create-react-class');
-const cx = require('classnames');
+const { useState, useEffect } = React;
-const SplitPane = createClass({
- displayName : 'SplitPane',
- getDefaultProps : function() {
- return {
- storageKey : 'naturalcrit-pane-split',
- onDragFinish : function(){}, //fires when dragging
- showDividerButtons : true
- };
- },
+const storageKey = 'naturalcrit-pane-split';
- getInitialState : function() {
- return {
- currentDividerPos : null,
- windowWidth : 0,
- isDragging : false,
- moveSource : false,
- moveBrew : false,
- showMoveArrows : true
- };
- },
+const SplitPane = (props)=>{
+ const {
+ onDragFinish = ()=>{},
+ showDividerButtons = true
+ } = props;
- pane1 : React.createRef(null),
- pane2 : React.createRef(null),
+ const [isDragging, setIsDragging] = useState(false);
+ const [dividerPos, setDividerPos] = useState(null);
+ const [moveSource, setMoveSource] = useState(false);
+ const [moveBrew, setMoveBrew] = useState(false);
+ const [showMoveArrows, setShowMoveArrows] = useState(true);
+ const [liveScroll, setLiveScroll] = useState(false);
- componentDidMount : function() {
- const dividerPos = window.localStorage.getItem(this.props.storageKey);
- if(dividerPos){
- this.setState({
- currentDividerPos : this.limitPosition(dividerPos, 0.1*(window.innerWidth-13), 0.9*(window.innerWidth-13)),
- userSetDividerPos : dividerPos,
- windowWidth : window.innerWidth
- });
- } else {
- this.setState({
- currentDividerPos : window.innerWidth / 2,
- userSetDividerPos : window.innerWidth / 2
- });
- }
- window.addEventListener('resize', this.handleWindowResize);
+ useEffect(()=>{
+ const savedPos = window.localStorage.getItem(storageKey);
+ setDividerPos(savedPos ? limitPosition(savedPos, 0.1 * (window.innerWidth - 13), 0.9 * (window.innerWidth - 13)) : window.innerWidth / 2);
+ setLiveScroll(window.localStorage.getItem('liveScroll') === 'true');
- // This lives here instead of in the initial render because you cannot touch localStorage until the componant mounts.
- const loadLiveScroll = window.localStorage.getItem('liveScroll') === 'true';
- this.setState({ liveScroll: loadLiveScroll });
- },
+ window.addEventListener('resize', handleResize);
+ return ()=>window.removeEventListener('resize', handleResize);
+ }, []);
- componentWillUnmount : function() {
- window.removeEventListener('resize', this.handleWindowResize);
- },
+ const limitPosition = (x, min = 1, max = window.innerWidth - 13)=>Math.round(Math.min(max, Math.max(min, x)));
- handleWindowResize : function() {
- // Allow divider to increase in size to last user-set position
- // Limit current position to between 10% and 90% of visible space
- const newLoc = this.limitPosition(this.state.userSetDividerPos, 0.1*(window.innerWidth-13), 0.9*(window.innerWidth-13));
-
- this.setState({
- currentDividerPos : newLoc,
- windowWidth : window.innerWidth
- });
- },
-
- limitPosition : function(x, min = 1, max = window.innerWidth - 13) {
- const result = Math.round(Math.min(max, Math.max(min, x)));
- return result;
- },
-
- handleUp : function(e){
+ //when resizing, the divider should grow smaller if less space is given, then grow back if the space is restored, to the original position
+ const handleResize = () =>setDividerPos(limitPosition(window.localStorage.getItem(storageKey), 0.1 * (window.innerWidth - 13), 0.9 * (window.innerWidth - 13)));
+
+ const handleUp =(e)=>{
e.preventDefault();
- if(this.state.isDragging){
- this.props.onDragFinish(this.state.currentDividerPos);
- window.localStorage.setItem(this.props.storageKey, this.state.currentDividerPos);
+ if(isDragging) {
+ onDragFinish(dividerPos);
+ window.localStorage.setItem(storageKey, dividerPos);
}
- this.setState({ isDragging: false });
- },
+ setIsDragging(false);
+ };
- handleDown : function(e){
+ const handleDown = (e)=>{
e.preventDefault();
- this.setState({ isDragging: true });
- //this.unFocus()
- },
-
- handleMove : function(e){
- if(!this.state.isDragging) return;
+ setIsDragging(true);
+ };
+ const handleMove = (e)=>{
+ if(!isDragging) return;
e.preventDefault();
- const newSize = this.limitPosition(e.pageX);
- this.setState({
- currentDividerPos : newSize,
- userSetDividerPos : newSize
- });
- },
+ setDividerPos(limitPosition(e.pageX));
+ };
- liveScrollToggle : function() {
- window.localStorage.setItem('liveScroll', String(!this.state.liveScroll));
- this.setState({ liveScroll: !this.state.liveScroll });
- },
- /*
- unFocus : function() {
- if(document.selection){
- document.selection.empty();
- }else{
- window.getSelection().removeAllRanges();
- }
- },
- */
+ const liveScrollToggle = ()=>{
+ window.localStorage.setItem('liveScroll', String(!liveScroll));
+ setLiveScroll(!liveScroll);
+ };
- setMoveArrows : function(newState) {
- if(this.state.showMoveArrows != newState){
- this.setState({
- showMoveArrows : newState
- });
- }
- },
-
- renderMoveArrows : function(){
- if(this.state.showMoveArrows) {
- return <>
- this.setState({ moveSource: !this.state.moveSource })} >
-
-
- this.setState({ moveBrew: !this.state.moveBrew })} >
-
-
-
-
-
- >;
- }
- },
-
- renderDivider : function(){
- return <>
- {this.props.showDividerButtons && this.renderMoveArrows()}
-
-
-
-
-
-
+ const renderMoveArrows = (showMoveArrows &&
+ <>
+
setMoveSource(!moveSource)} >
+
- >;
- },
+
setMoveBrew(!moveBrew)} >
+
+
+
+
+
+ >
+ );
- render : function(){
- return
-
- {React.cloneElement(this.props.children[0], {
- ...(this.props.showDividerButtons && {
- moveBrew : this.state.moveBrew,
- moveSource : this.state.moveSource,
- liveScroll : this.state.liveScroll,
- setMoveArrows : this.setMoveArrows,
- }),
- })}
+ const renderDivider = (
+
+ {showDividerButtons && renderMoveArrows}
+
+
+
+
+
+
+ );
+
+ return (
+
+
+ {props.children[0]}
- {this.renderDivider()}
-
{this.props.children[1]}
-
;
- }
-});
+ {renderDivider}
+ {props.children[1]}
+
+ );
+};
-const Pane = createClass({
- displayName : 'Pane',
- getDefaultProps : function() {
- return {
- width : null
- };
- },
- render : function(){
- let styles = {};
- if(this.props.width){
- styles = {
- flex : 'none',
- width : `${this.props.width}px`
- };
- } else {
- styles = {
- pointerEvents : this.props.isDragging ? 'none' : 'auto' //Disable mouse capture in the rightmost pane; dragging into the iframe drops the divider otherwise
- };
- }
+const Pane = ({ width, children, isDragging, moveBrew, moveSource, liveScroll, setMoveArrows })=>{
+ const styles = width
+ ? { flex: 'none', width: `${width}px` }
+ : { pointerEvents: isDragging ? 'none' : 'auto' }; //Disable mouse capture in the right pane; else dragging into the iframe drops the divider
- return
- {this.props.children}
-
;
- }
-});
+ return (
+
+ {React.cloneElement(children, { moveBrew, moveSource, liveScroll, setMoveArrows })}
+
+ );
+};
module.exports = SplitPane;
diff --git a/shared/naturalcrit/splitPane/splitPane.less b/shared/naturalcrit/splitPane/splitPane.less
index e5b3dd7f8..8b61097be 100644
--- a/shared/naturalcrit/splitPane/splitPane.less
+++ b/shared/naturalcrit/splitPane/splitPane.less
@@ -1,69 +1,68 @@
-.splitPane{
+.splitPane {
position : relative;
display : flex;
+ flex-direction : row;
height : 100%;
outline : none;
- flex-direction : row;
- .pane{
+ .pane {
+ flex : 1;
overflow-x : hidden;
overflow-y : hidden;
- flex : 1;
}
- .divider{
- touch-action : none;
+ .divider {
+ position : relative;
display : table;
- height : 100%;
width : 15px;
- cursor : ew-resize;
- background-color : #bbb;
+ height : 100%;
text-align : center;
- .dots{
+ touch-action : none;
+ cursor : ew-resize;
+ background-color : #BBBBBB;
+ .dots {
display : table-cell;
- vertical-align : middle;
text-align : center;
- i{
+ vertical-align : middle;
+ i {
display : block !important;
margin : 10px 0px;
font-size : 6px;
- color : #666;
+ color : #666666;
}
}
- &:hover{
- background-color: #999;
- }
+ &:hover,&.dragging { background-color : #999999; }
}
- .arrow{
+ .arrow {
position : absolute;
+ left : 50%;
+ z-index : 999;
width : 25px;
height : 25px;
- border : 2px solid #bbb;
- border-radius : 15px;
- text-align : center;
font-size : 1.2em;
+ text-align : center;
cursor : pointer;
- background-color : #ddd;
- z-index : 999;
- box-shadow : 0 4px 5px #0000007f;
- &.left{
+ background-color : #DDDDDD;
+ border : 2px solid #BBBBBB;
+ border-radius : 15px;
+ box-shadow : 0 4px 5px #0000007F;
+ translate : -50%;
+ &.left {
.tooltipLeft('Jump to location in Editor');
top : 30px;
}
- &.right{
+ &.right {
.tooltipRight('Jump to location in Preview');
top : 60px;
}
- &.lock{
+ &.lock {
.tooltipRight('De-sync Editor and Preview locations.');
- top : 90px;
- background: #666;
+ top : 90px;
+ background : #666666;
}
- &.unlock{
+ &.unlock {
.tooltipRight('Sync Editor and Preview locations');
top : 90px;
}
- &:hover{
- background-color: #666;
- }
+ &:hover { background-color : #666666; }
}
}