diff --git a/client/components/dialog.jsx b/client/components/dialog.jsx
new file mode 100644
index 000000000..2057ecb87
--- /dev/null
+++ b/client/components/dialog.jsx
@@ -0,0 +1,29 @@
+// Dialog box, for popups and modal blocking messages
+const React = require('react');
+const { useRef, useEffect } = React;
+
+function Dialog({ dismissKey, closeText = 'Close', blocking = false, ...rest }) {
+ const dialogRef = useRef(null);
+
+ useEffect(()=>{
+ if(!dismissKey || !localStorage.getItem(dismissKey)) {
+ blocking ? dialogRef.current?.showModal() : dialogRef.current?.show();
+ }
+ }, []);
+
+ const dismiss = ()=>{
+ dismissKey && localStorage.setItem(dismissKey, true);
+ dialogRef.current?.close();
+ };
+
+ return (
+
+ {rest.children}
+
+ {closeText}
+
+
+ );
+};
+
+export default Dialog;
diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx
index 6a4040b4d..8168f9933 100644
--- a/client/homebrew/brewRenderer/brewRenderer.jsx
+++ b/client/homebrew/brewRenderer/brewRenderer.jsx
@@ -203,6 +203,12 @@ const BrewRenderer = (props)=>{
: null}
+
+
+
+
+
+
{/*render in iFrame so broken code doesn't crash the site.*/}
{
tabIndex={-1}
style={{ height: state.height }}>
-
-
-
-
-
{baseThemePath &&
diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx
index 6872d6c3e..cca60bbec 100644
--- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx
+++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx
@@ -1,80 +1,45 @@
require('./notificationPopup.less');
const React = require('react');
-const createClass = require('create-react-class');
const _ = require('lodash');
+import Dialog from '../../../components/dialog.jsx';
+
const DISMISS_KEY = 'dismiss_notification12-04-23';
+const DISMISS_BUTTON = ;
-const NotificationPopup = createClass({
- displayName : 'NotificationPopup',
- getInitialState : function() {
- return {
- notifications : {}
- };
- },
- componentDidMount : function() {
- this.checkNotifications();
- window.addEventListener('resize', this.checkNotifications);
- },
- componentWillUnmount : function() {
- window.removeEventListener('resize', this.checkNotifications);
- },
- notifications : {
- psa : function(){
- return (
- <>
-
- Don't store IMAGES in Google Drive
- Google Drive is not an image service, and will block images from being used
- in brews if they get more views than expected. Google has confirmed they won't fix
- this, so we recommend you look for another image hosting service such as imgur, ImgBB or Google Photos.
-
+const NotificationPopup = ()=>{
+ return
+
+
+
Notice
+ This website is always improving and we are still adding new features and squashing bugs. Keep the following in mind:
+
+
+
+ Don't store IMAGES in Google Drive
+ Google Drive is not an image service, and will block images from being used
+ in brews if they get more views than expected. Google has confirmed they won't fix
+ this, so we recommend you look for another image hosting service such as imgur, ImgBB or Google Photos.
+
-
- Don't delete your Homebrewery folder on Google Drive!
- We have had several reports of users losing their brews, not realizing
- that they had deleted the files on their Google Drive. If you have a Homebrewery folder
- on your Google Drive with *.txt files inside, do not delete it !
- We cannot help you recover files that you have deleted from your own
- Google Drive.
-
+
+ Don't delete your Homebrewery folder on Google Drive!
+ We have had several reports of users losing their brews, not realizing
+ that they had deleted the files on their Google Drive. If you have a Homebrewery folder
+ on your Google Drive with *.txt files inside, do not delete it !
+ We cannot help you recover files that you have deleted from your own
+ Google Drive.
+
-
- Protect your work!
- If you opt not to use your Google Drive, keep in mind that we do not save a history of your projects. Please make frequent backups of your brews!
-
- See the FAQ
- to learn how to avoid losing your work!
-
- >
- );
- }
- },
- checkNotifications : function(){
- const hideDismiss = localStorage.getItem(DISMISS_KEY);
- if(hideDismiss) return this.setState({ notifications: {} });
-
- this.setState({
- notifications : _.mapValues(this.notifications, (fn)=>{ return fn(); }) //Convert notification functions into their return text value
- });
- },
- dismiss : function(){
- localStorage.setItem(DISMISS_KEY, true);
- this.checkNotifications();
- },
- render : function(){
- if(_.isEmpty(this.state.notifications)) return null;
-
- return
-
-
-
-
Notice
- This website is always improving and we are still adding new features and squashing bugs. Keep the following in mind:
-
- {_.values(this.state.notifications)}
- ;
- }
-});
+
+ Protect your work!
+ If you opt not to use your Google Drive, keep in mind that we do not save a history of your projects. Please make frequent backups of your brews!
+
+ See the FAQ
+ to learn how to avoid losing your work!
+
+
+ ;
+};
module.exports = NotificationPopup;
diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less
index dfd3c6c63..26d764aff 100644
--- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less
+++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less
@@ -1,64 +1,60 @@
-.popups{
+.popups {
position : fixed;
top : @navbarHeight;
- right : 15px;
+ right : 24px;
z-index : 10001;
width : 450px;
}
-.notificationPopup{
+.notificationPopup {
position : relative;
- display : inline-block;
width : 100%;
padding : 15px;
padding-bottom : 10px;
padding-left : 25px;
- background-color : @blue;
color : white;
- a{
- color : #e0e5c1;
+ background-color : @blue;
+ border : none;
+ &[open] { display : inline-block; }
+ a {
font-weight : 800;
+ color : #E0E5C1;
}
- i.info{
+ i.info {
position : absolute;
top : 12px;
left : 12px;
- opacity : 0.8;
font-size : 2.5em;
+ opacity : 0.8;
}
- i.dismiss{
- position : absolute;
- top : 10px;
- right : 10px;
- cursor : pointer;
- opacity : 0.6;
- &:hover{
- opacity : 1;
- }
+ button.dismiss {
+ position : absolute;
+ top : 10px;
+ right : 10px;
+ cursor : pointer;
+ background-color : transparent;
+ opacity : 0.6;
+ &:hover { opacity : 1; }
}
- .header {
- padding-left : 50px;
- }
- small{
- opacity : 0.7;
+ .header { padding-left : 50px; }
+ small {
font-size : 0.6em;
+ opacity : 0.7;
}
- h3{
+ h3 {
font-size : 1.1em;
font-weight : 800;
}
- ul{
+ ul {
margin-top : 15px;
font-size : 0.8em;
list-style-position : outside;
list-style-type : disc;
- li{
+ li {
+ margin-top : 1.4em;
font-size : 0.8em;
line-height : 1.4em;
- margin-top : 1.4em;
- em{
- font-weight : 800;
- }
+ em { font-weight : 800; }
}
}
}
diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx
index 20282f9b5..48d0f3fe5 100644
--- a/client/homebrew/pages/editPage/editPage.jsx
+++ b/client/homebrew/pages/editPage/editPage.jsx
@@ -20,6 +20,8 @@ const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
const Editor = require('../../editor/editor.jsx');
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
+const LockNotification = require('./lockNotification/lockNotification.jsx');
+
const Markdown = require('naturalcrit/markdown.js');
const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js');
@@ -52,7 +54,8 @@ const EditPage = createClass({
autoSave : true,
autoSaveWarning : false,
unsavedTime : new Date(),
- currentEditorPage : 0
+ currentEditorPage : 0,
+ displayLockMessage : this.props.brew.lock || false
};
},
@@ -393,6 +396,7 @@ const EditPage = createClass({
{this.renderNavbar()}
+ {this.props.brew.lock &&
}
{},
+ message : '',
+ ...props
+ };
+
+ const removeLock = ()=>{
+ alert(`Not yet implemented - ID ${props.shareId}`);
+ };
+
+ return
+ BREW LOCKED
+ This brew been locked by the Administrators. It will not be accessible by any method other than the Editor until the lock is removed.
+
+ LOCK REASON
+ {props.message || 'Unable to retrieve Lock Message'}
+
+ Once you have resolved this issue, click REQUEST LOCK REMOVAL to notify the Administrators for review.
+ Click CONTINUE TO EDITOR to temporarily hide this notification; it will reappear the next time the page is reloaded.
+ REQUEST LOCK REMOVAL
+ ;
+};
+
+module.exports = LockNotification;
diff --git a/client/homebrew/pages/editPage/lockNotification/lockNotification.less b/client/homebrew/pages/editPage/lockNotification/lockNotification.less
new file mode 100644
index 000000000..54f1a9569
--- /dev/null
+++ b/client/homebrew/pages/editPage/lockNotification/lockNotification.less
@@ -0,0 +1,27 @@
+.lockNotification {
+ z-index : 1;
+ width : 80%;
+ padding : 10px;
+ margin : 5% 10%;
+ line-height : 1.5em;
+ color : black;
+ text-align : center;
+ background-color : #CCCCCC;
+
+ &::backdrop { background-color : #000000AA; }
+
+ button {
+ margin : 10px;
+ color : white;
+ background-color : #333333;
+
+ &:hover { background-color : #777777; }
+ }
+
+ h1, h3 {
+ font-family : 'Open Sans', sans-serif;
+ font-weight : 800;
+ }
+ h1 { font-size : 24px; }
+ h3 { font-size : 18px; }
+}
diff --git a/client/homebrew/pages/errorPage/errors/errorIndex.js b/client/homebrew/pages/errorPage/errors/errorIndex.js
index 7fa24dddc..58725fe3f 100644
--- a/client/homebrew/pages/errorPage/errors/errorIndex.js
+++ b/client/homebrew/pages/errorPage/errors/errorIndex.js
@@ -140,7 +140,7 @@ const errorIndex = (props)=>{
'100' : dedent`
## This brew has been locked.
- Please contact the Administrators to unlock this document.
+ Only an author may request that this lock is removed.
:
diff --git a/server/homebrew.api.js b/server/homebrew.api.js
index ae1abf787..f755c8f23 100644
--- a/server/homebrew.api.js
+++ b/server/homebrew.api.js
@@ -55,7 +55,7 @@ const api = {
stub = stub?.toObject();
if(stub?.lock?.locked && accessType != 'edit') {
- throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.message, brewId: stub.shareId, brewTitle: stub.title };
+ throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title };
}
// If there is a google id, try to find the google brew
diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js
index 8a4748e38..c8539bf63 100644
--- a/server/homebrew.api.spec.js
+++ b/server/homebrew.api.spec.js
@@ -300,7 +300,7 @@ describe('Tests for api', ()=>{
});
it('access is denied to a locked brew', async()=>{
- const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, message: 'brew locked' } };
+ const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, shareMessage: 'brew locked' } };
model.get = jest.fn(()=>toBrewPromise(lockBrew));
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
diff --git a/shared/homebrewery/renderWarnings/renderWarnings.jsx b/shared/homebrewery/renderWarnings/renderWarnings.jsx
index 6028f1708..e9c5f6f57 100644
--- a/shared/homebrewery/renderWarnings/renderWarnings.jsx
+++ b/shared/homebrewery/renderWarnings/renderWarnings.jsx
@@ -3,7 +3,7 @@ const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
-const DISMISS_KEY = 'dismiss_render_warning';
+import Dialog from '../../../client/components/dialog.jsx';
const RenderWarnings = createClass({
displayName : 'RenderWarnings',
@@ -34,9 +34,6 @@ const RenderWarnings = createClass({
},
},
checkWarnings : function(){
- const hideDismiss = localStorage.getItem(DISMISS_KEY);
- if(hideDismiss) return this.setState({ warnings: {} });
-
this.setState({
warnings : _.reduce(this.warnings, (r, fn, type)=>{
const element = fn();
@@ -45,20 +42,18 @@ const RenderWarnings = createClass({
}, {})
});
},
- dismiss : function(){
- localStorage.setItem(DISMISS_KEY, true);
- this.checkWarnings();
- },
render : function(){
if(_.isEmpty(this.state.warnings)) return null;
- return
-
+ const DISMISS_KEY = 'dismiss_render_warning';
+ const DISMISS_TEXT = ;
+
+ return
Render Warnings
If this homebrew is rendering badly if might be because of the following:
{_.values(this.state.warnings)}
- ;
+ ;
}
});
diff --git a/shared/homebrewery/renderWarnings/renderWarnings.less b/shared/homebrewery/renderWarnings/renderWarnings.less
index 4b038a11a..70799092a 100644
--- a/shared/homebrewery/renderWarnings/renderWarnings.less
+++ b/shared/homebrewery/renderWarnings/renderWarnings.less
@@ -1,53 +1,48 @@
-.renderWarnings{
- position : relative;
- float : right;
- display : inline-block;
+.renderWarnings {
+ position : relative;
+ float : right;
width : 350px;
padding : 20px;
padding-bottom : 10px;
padding-left : 85px;
margin-bottom : 10px;
- background-color : @yellow;
color : white;
- a{
- font-weight : 800;
- }
- i.ohno{
+ background-color : @yellow;
+ border : none;
+ a { font-weight : 800; }
+ i.ohno {
position : absolute;
top : 24px;
left : 24px;
- opacity : 0.8;
font-size : 2.5em;
+ opacity : 0.8;
}
- i.dismiss{
- position : absolute;
- top : 10px;
- right : 10px;
- cursor : pointer;
- opacity : 0.6;
- &:hover{
- opacity : 1;
- }
+ button.dismiss {
+ position : absolute;
+ top : 10px;
+ right : 10px;
+ cursor : pointer;
+ background-color : transparent;
+ opacity : 0.6;
+ &:hover { opacity : 1; }
}
- small{
- opacity : 0.7;
+ small {
font-size : 0.6em;
+ opacity : 0.7;
}
- h3{
+ h3 {
font-size : 1.1em;
font-weight : 800;
}
- ul{
+ ul {
margin-top : 15px;
font-size : 0.8em;
list-style-position : outside;
list-style-type : disc;
- li{
+ li {
font-size : 0.8em;
line-height : 1.6em;
- em{
- font-weight : 800;
- }
+ em { font-weight : 800; }
}
}
}
\ No newline at end of file