diff --git a/client/homebrew/pages/basePages/editorPage/editorPage.jsx b/client/homebrew/pages/basePages/editorPage/editorPage.jsx
deleted file mode 100644
index 99a5c2b52..000000000
--- a/client/homebrew/pages/basePages/editorPage/editorPage.jsx
+++ /dev/null
@@ -1,578 +0,0 @@
-/* eslint-disable max-lines */
-require('./editorPage.less');
-const React = require('react');
-const createClass = require('create-react-class');
-const _ = require('lodash');
-const request = require('superagent');
-const { Meta } = require('vitreum/headtags');
-
-const Nav = require('naturalcrit/nav/nav.jsx');
-const Navbar = require('../../../navbar/navbar.jsx');
-
-const NewBrew = require('../../../navbar/newbrew.navitem.jsx');
-const ReportIssue = require('../../../navbar/issue.navitem.jsx');
-const PrintLink = require('../../../navbar/print.navitem.jsx');
-const Account = require('../../../navbar/account.navitem.jsx');
-const RecentNavItem = require('../../../navbar/recent.navitem.jsx').both;
-
-const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
-const Editor = require('../../../editor/editor.jsx');
-const BrewRenderer = require('../../../brewRenderer/brewRenderer.jsx');
-
-const Markdown = require('naturalcrit/markdown.js');
-
-const googleDriveActive = require('../../../googleDrive.png');
-const googleDriveInactive = require('../../../googleDriveMono.png');
-
-const SAVE_TIMEOUT = 3000;
-
-const BREWKEY = 'homebrewery-new';
-const STYLEKEY = 'homebrewery-new-style';
-const METAKEY = 'homebrewery-new-meta';
-
-const EditorPage = createClass({
- getDefaultProps : function() {
- return {
- brew : {
- text : '',
- style : '',
- shareId : null,
- editId : null,
- createdAt : null,
- updatedAt : null,
- gDrive : false,
- trashed : false,
-
- title : '',
- description : '',
- tags : '',
- published : false,
- authors : [],
- systems : [],
- renderer : 'legacy'
- },
- pageType : 'edit',
- googleDriveOptions : [
- 'DRIVE > HB',
- 'HB > DRIVE'
- ]
- };
- },
-
- getInitialState : function() {
- return {
- brew : this.props.brew,
- isSaving : false,
- isPending : false,
- alertTrashedGoogleBrew : this.props.brew.trashed,
- alertLoginToTransfer : false,
- saveGoogle : this.props.brew.googleId ? true : false,
- confirmGoogleTransfer : false,
- errors : null,
- htmlErrors : Markdown.validate(this.props.brew.text),
- url : ''
- };
- // return {
- // brew : {
- // text : brew.text || '',
- // style : brew.style || undefined,
- // gDrive : false,
- // title : brew.title || '',
- // description : brew.description || '',
- // tags : brew.tags || '',
- // published : false,
- // authors : [],
- // systems : brew.systems || [],
- // renderer : brew.renderer || 'legacy'
- // },
-
- // isSaving : false,
- // isPending : false,
- // alertTrashedGoogleBrew : this.props.brew.trashed,
- // alertLoginToTransfer : false,
- // saveGoogle : (global.account && global.account.googleId ? true : false),
- // confirmGoogleTransfer : false,
- // errors : null,
- // htmlErrors : Markdown.validate(brew.text),
- // url : ''
- // };
- },
- savedBrew : null,
-
- componentDidMount : function(){
- this.setState({
- url : window.location.href
- });
-
- this.savedBrew = JSON.parse(JSON.stringify(this.props.brew)); //Deep copy
-
- this.trySave();
- window.onbeforeunload = ()=>{
- if(this.state.isSaving || this.state.isPending){
- return 'You have unsaved changes!';
- }
- };
-
- this.setState((prevState)=>({
- htmlErrors : Markdown.validate(prevState.brew.text)
- }));
-
- document.addEventListener('keydown', this.handleControlKeys);
- },
- componentWillUnmount : function() {
- window.onbeforeunload = function(){};
- document.removeEventListener('keydown', this.handleControlKeys);
- },
-
- handleControlKeys : function(e){
- if(!(e.ctrlKey || e.metaKey)) return;
- const S_KEY = 83;
- const P_KEY = 80;
- if(e.keyCode == S_KEY) this.save();
- if(e.keyCode == P_KEY) window.open(`/print/${this.processShareId()}?dialog=true`, '_blank').focus();
- if(e.keyCode == P_KEY || e.keyCode == S_KEY){
- e.stopPropagation();
- e.preventDefault();
- }
- },
-
- isEdit : function(){
- return this.props.pageType == 'edit';
- },
-
- isNew : function(){
- return this.props.pageType == 'new';
- },
-
- handleSplitMove : function(){
- this.refs.editor.update();
- },
-
- handleTextChange : function(text){
- //If there are errors, run the validator on every change to give quick feedback
- let htmlErrors = this.state.htmlErrors;
- if(htmlErrors.length) htmlErrors = Markdown.validate(text);
-
- this.setState((prevState)=>({
- brew : _.merge({}, prevState.brew, { text: text }),
- isPending : true,
- htmlErrors : htmlErrors
- }), ()=>this.trySave());
- },
-
- handleStyleChange : function(style){
- this.setState((prevState)=>({
- brew : _.merge({}, prevState.brew, { style: style }),
- isPending : true
- }), ()=>this.trySave());
- },
-
- handleMetaChange : function(metadata){
- this.setState((prevState)=>({
- brew : _.merge({}, prevState.brew, metadata),
- isPending : true,
- }), ()=>this.trySave());
-
- },
-
- hasChanges : function(){
- return !_.isEqual(this.state.brew, this.savedBrew);
- },
-
- trySave : function(){
- if(!this.isEdit()) return;
- if(!this.debounceSave) this.debounceSave = _.debounce(this.save, SAVE_TIMEOUT);
- if(this.hasChanges()){
- this.debounceSave();
- } else {
- this.debounceSave.cancel();
- }
- },
-
- handleGoogleClick : function(){
- if(!global.account?.googleId) {
- this.setState({
- alertLoginToTransfer : true
- });
- return;
- }
- this.setState((prevState)=>({
- confirmGoogleTransfer : !prevState.confirmGoogleTransfer
- }));
- this.clearErrors();
- },
-
- closeAlerts : function(event){
- event.stopPropagation(); //Only handle click once so alert doesn't reopen
- this.setState({
- alertTrashedGoogleBrew : false,
- alertLoginToTransfer : false,
- confirmGoogleTransfer : false
- });
- },
-
- toggleGoogleStorage : function(){
- this.setState((prevState)=>({
- saveGoogle : !prevState.saveGoogle,
- isSaving : false,
- errors : null
- }), ()=>this.isEdit() && this.save());
- },
-
- clearErrors : function(){
- this.setState({
- errors : null,
- isSaving : false
-
- });
- },
-
- save : async function(){
- this.setState((prevState)=>({
- isSaving : true,
- errors : null,
- htmlErrors : Markdown.validate(prevState.brew.text)
- }));
-
- if(this.isEdit()){
- if(this.debounceSave && this.debounceSave.cancel) this.debounceSave.cancel();
-
- const transfer = this.state.saveGoogle == _.isNil(this.state.brew.googleId);
-
- const brew = this.state.brew;
- brew.pageCount = ((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1;
-
- if(this.state.saveGoogle) {
- if(transfer) {
- const res = await request
- .post('/api/newGoogle/')
- .send(brew)
- .catch((err)=>{
- console.log(err.status === 401
- ? 'Not signed in!'
- : 'Error Transferring to Google!');
- this.setState({ errors: err, saveGoogle: false });
- });
-
- if(!res) { return; }
-
- console.log('Deleting Local Copy');
- await request.delete(`/api/${brew.editId}`)
- .send()
- .catch((err)=>{
- console.log('Error deleting Local Copy');
- });
-
- this.savedBrew = res.body;
- history.replaceState(null, null, `/edit/${this.savedBrew.googleId}${this.savedBrew.editId}`); //update URL to match doc ID
- } else {
- const res = await request
- .put(`/api/updateGoogle/${brew.editId}`)
- .send(brew)
- .catch((err)=>{
- console.log(err.status === 401
- ? 'Not signed in!'
- : 'Error Saving to Google!');
- this.setState({ errors: err });
- return;
- });
-
- this.savedBrew = res.body;
- }
- } else {
- if(transfer) {
- const res = await request.post('/api')
- .send(brew)
- .catch((err)=>{
- console.log('Error creating Local Copy');
- this.setState({ errors: err });
- return;
- });
-
- await request.get(`/api/removeGoogle/${brew.googleId}${brew.editId}`)
- .send()
- .catch((err)=>{
- console.log('Error Deleting Google Brew');
- });
-
- this.savedBrew = res.body;
- history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); //update URL to match doc ID
- } else {
- const res = await request
- .put(`/api/update/${brew.editId}`)
- .send(brew)
- .catch((err)=>{
- console.log('Error Updating Local Brew');
- this.setState({ errors: err });
- return;
- });
-
- this.savedBrew = res.body;
- }
- }
-
- this.setState((prevState)=>({
- brew : _.merge({}, prevState.brew, {
- googleId : this.savedBrew.googleId ? this.savedBrew.googleId : null,
- editId : this.savedBrew.editId,
- shareId : this.savedBrew.shareId
- }),
- isPending : false,
- isSaving : false,
- }));
- }
-
- if(this.isNew()){
- 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);
- };
-
- brew.pageCount=((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1;
-
- if(this.state.saveGoogle) {
- const res = await request
- .post('/api/newGoogle/')
- .send(brew)
- .catch((err)=>{
- console.log(err.status === 401
- ? 'Not signed in!'
- : 'Error Creating New Google Brew!');
- this.setState({ isSaving: false, errors: err });
- return;
- });
-
- brew = res.body;
- localStorage.removeItem(BREWKEY);
- localStorage.removeItem(STYLEKEY);
- localStorage.removeItem(METAKEY);
- window.location = `/edit/${brew.googleId}${brew.editId}`;
- } else {
- request.post('/api')
- .send(brew)
- .end((err, res)=>{
- if(err){
- this.setState({
- isSaving : false
- });
- return;
- }
- window.onbeforeunload = function(){};
- brew = res.body;
- localStorage.removeItem(BREWKEY);
- localStorage.removeItem(STYLEKEY);
- localStorage.removeItem(METAKEY);
- window.location = `/edit/${brew.editId}`;
- });
- }
- }
- },
-
- renderGoogleDriveIcon : function(){
- return
- {this.state.saveGoogle
- ?
- :
- }
-
- {this.state.confirmGoogleTransfer &&
-
- { this.state.saveGoogle
- ? this.props.googleDriveOptions[0]
- : this.props.googleDriveOptions[1]
- }
-
-
- Yes
-
-
- No
-
-
- }
-
- {this.state.alertLoginToTransfer &&
-
- You must be signed in to a Google account to transfer
- between the homebrewery and Google Drive!
-
-
- Sign In
-
-
-
- Not Now
-
-
- }
- ;
- },
-
- renderSaveButton : function(){
- if(this.state.errors){
- let errMsg = '';
- try {
- errMsg += `${this.state.errors.toString()}\n\n`;
- errMsg += `\`\`\`\n${this.state.errors.stack}\n`;
- errMsg += `${JSON.stringify(this.state.errors.response.error, null, ' ')}\n\`\`\``;
- console.log(errMsg);
- } catch (e){}
-
- if(this.state.errors.status == '401'){
- return
- Oops!
-
- You must be signed in to a Google account
- to save this to
Google Drive!
-
-
- Sign In
-
-
-
- Not Now
-
-
- ;
- }
-
- if(this.state.errors.status == '403' && this.state.errors.response.body.errors[0].reason == 'insufficientPermissions'){
- return
- Oops!
-
- Looks like your Google credentials have
- expired! Visit the log in page to sign out
- and sign back in with Google
- to save this to Google Drive!
-
-
- Sign In
-
-
-
- Not Now
-
-
- ;
- }
-
- return
- Oops!
-
- Looks like there was a problem saving.
- Report the issue
- here
- .
-
- ;
- }
-
- if(this.state.isSaving){
- return saving...;
- }
- if(this.state.isPending && this.hasChanges()){
- return Save Now;
- }
- if(!this.state.isPending && !this.state.isSaving){
- return saved.;
- }
- },
-
- processShareId : function() {
- return this.state.brew.googleId ?
- this.state.brew.googleId + this.state.brew.shareId :
- this.state.brew.shareId;
- },
-
- getRedditLink : function(){
-
- const shareLink = this.processShareId();
- const systems = this.props.brew.systems.length > 0 ? ` [${this.props.brew.systems.join(' - ')}]` : '';
- const title = `${this.props.brew.title} ${systems}`;
- const text = `Hey guys! I've been working on this homebrew. I'd love your feedback. Check it out.
-
-**[Homebrewery Link](https://homebrewery.naturalcrit.com/share/${shareLink})**`;
-
- return `https://www.reddit.com/r/UnearthedArcana/submit?title=${encodeURIComponent(title)}&text=${encodeURIComponent(text)}`;
- },
-
- renderNavbar : function(){
- const shareLink = this.processShareId();
-
- return
-
- {this.state.alertTrashedGoogleBrew &&
-
- This brew is currently in your Trash folder on Google Drive!
If you want to keep it, make sure to move it before it is deleted permanently!
-
- OK
-
-
- }
-
-
- {this.state.brew.title}
-
-
-
- {this.renderGoogleDriveIcon()}
- {this.renderSaveButton()}
-
-
- {this.isEdit() && <>
-
-
- share
-
-
- view
-
- {navigator.clipboard.writeText(`https://homebrewery.naturalcrit.com/share/${shareLink}`);}}>
- copy url
-
-
- post to reddit
-
-
-
- >
- }
-
-
-
-
- ;
- },
-
- render : function(){
- return
-
- {this.renderNavbar()}
-
-
-
-
-
-
-
-
;
- }
-});
-
-module.exports = EditorPage;
diff --git a/client/homebrew/pages/basePages/editorPage/editorPage.less b/client/homebrew/pages/basePages/editorPage/editorPage.less
deleted file mode 100644
index 0cbfadcbd..000000000
--- a/client/homebrew/pages/basePages/editorPage/editorPage.less
+++ /dev/null
@@ -1,99 +0,0 @@
-@keyframes glideDown {
- 0% {transform : translate(-50% + 3px, 0px);
- opacity : 0;}
- 100% {transform : translate(-50% + 3px, 10px);
- opacity : 1;}
-}
-.editPage{
- .navItem.save{
- width : 106px;
- text-align : center;
- position : relative;
- &.saved{
- cursor : initial;
- color : #666;
- }
- &.error{
- position : relative;
- background-color : @red;
- }
- }
- .googleDriveStorage {
- position : relative;
- }
- .googleDriveStorage img{
- height : 20px;
- padding : 0px;
- margin : -5px;
- }
- .errorContainer{
- animation-name: glideDown;
- animation-duration: 0.4s;
- position : absolute;
- top : 100%;
- left : 50%;
- z-index : 100000;
- width : 140px;
- padding : 3px;
- color : white;
- background-color : #333;
- border : 3px solid #444;
- border-radius : 5px;
- transform : translate(-50% + 3px, 10px);
- text-align : center;
- font-size : 10px;
- font-weight : 800;
- text-transform : uppercase;
- a{
- color : @teal;
- }
- &:before {
- content: "";
- width: 0px;
- height: 0px;
- position: absolute;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-top: 10px solid transparent;
- border-bottom: 10px solid #444;
- left: 53px;
- top: -23px;
- }
- &:after {
- content: "";
- width: 0px;
- height: 0px;
- position: absolute;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-top: 10px solid transparent;
- border-bottom: 10px solid #333;
- left: 53px;
- top: -19px;
- }
- .deny {
- width : 48%;
- margin : 1px;
- padding : 5px;
- background-color : #333;
- display : inline-block;
- border-left : 1px solid #666;
- .animate(background-color);
- &:hover{
- background-color : red;
- }
- }
- .confirm {
- width : 48%;
- margin : 1px;
- padding : 5px;
- background-color : #333;
- display : inline-block;
- color : white;
- .animate(background-color);
- &:hover{
- background-color : teal;
- }
- }
- }
-}
diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx
index 8e70cee32..ee4f41f5b 100644
--- a/client/homebrew/pages/editPage/editPage.jsx
+++ b/client/homebrew/pages/editPage/editPage.jsx
@@ -3,8 +3,28 @@ require('./editPage.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
+const request = require('superagent');
+const { Meta } = require('vitreum/headtags');
-const EditorPage = require('../basePages/editorPage/editorPage.jsx');
+const Nav = require('naturalcrit/nav/nav.jsx');
+const Navbar = require('../../navbar/navbar.jsx');
+
+const NewBrew = require('../../navbar/newbrew.navitem.jsx');
+const ReportIssue = require('../../navbar/issue.navitem.jsx');
+const PrintLink = require('../../navbar/print.navitem.jsx');
+const Account = require('../../navbar/account.navitem.jsx');
+const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
+
+const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
+const Editor = require('../../editor/editor.jsx');
+const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
+
+const Markdown = require('naturalcrit/markdown.js');
+
+const googleDriveActive = require('../../googleDrive.png');
+const googleDriveInactive = require('../../googleDriveMono.png');
+
+const SAVE_TIMEOUT = 3000;
const EditPage = createClass({
getDefaultProps : function() {
@@ -30,17 +50,431 @@ const EditPage = createClass({
};
},
- render : function(){
- const googleDriveOptions = [
- 'Would you like to transfer this brew from your Google Drive storage back to the Homebrewery?',
- 'Would you like to transfer this brew from the Homebrewery to your personal Google Drive storage?'
- ];
+ getInitialState : function() {
+ return {
+ brew : this.props.brew,
+ isSaving : false,
+ isPending : false,
+ alertTrashedGoogleBrew : this.props.brew.trashed,
+ alertLoginToTransfer : false,
+ saveGoogle : this.props.brew.googleId ? true : false,
+ confirmGoogleTransfer : false,
+ errors : null,
+ htmlErrors : Markdown.validate(this.props.brew.text),
+ url : ''
+ };
+ },
+ savedBrew : null,
- return ;
+ componentDidMount : function(){
+ this.setState({
+ url : window.location.href
+ });
+
+ this.savedBrew = JSON.parse(JSON.stringify(this.props.brew)); //Deep copy
+
+ this.trySave();
+ window.onbeforeunload = ()=>{
+ if(this.state.isSaving || this.state.isPending){
+ return 'You have unsaved changes!';
+ }
+ };
+
+ this.setState((prevState)=>({
+ htmlErrors : Markdown.validate(prevState.brew.text)
+ }));
+
+ document.addEventListener('keydown', this.handleControlKeys);
+ },
+ componentWillUnmount : function() {
+ window.onbeforeunload = function(){};
+ document.removeEventListener('keydown', this.handleControlKeys);
+ },
+
+ handleControlKeys : function(e){
+ if(!(e.ctrlKey || e.metaKey)) return;
+ const S_KEY = 83;
+ const P_KEY = 80;
+ if(e.keyCode == S_KEY) this.save();
+ if(e.keyCode == P_KEY) window.open(`/print/${this.processShareId()}?dialog=true`, '_blank').focus();
+ if(e.keyCode == P_KEY || e.keyCode == S_KEY){
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ },
+
+ handleSplitMove : function(){
+ this.refs.editor.update();
+ },
+
+ handleTextChange : function(text){
+ //If there are errors, run the validator on every change to give quick feedback
+ let htmlErrors = this.state.htmlErrors;
+ if(htmlErrors.length) htmlErrors = Markdown.validate(text);
+
+ this.setState((prevState)=>({
+ brew : _.merge({}, prevState.brew, { text: text }),
+ isPending : true,
+ htmlErrors : htmlErrors
+ }), ()=>this.trySave());
+ },
+
+ handleStyleChange : function(style){
+ this.setState((prevState)=>({
+ brew : _.merge({}, prevState.brew, { style: style }),
+ isPending : true
+ }), ()=>this.trySave());
+ },
+
+ handleMetaChange : function(metadata){
+ this.setState((prevState)=>({
+ brew : _.merge({}, prevState.brew, metadata),
+ isPending : true,
+ }), ()=>this.trySave());
+
+ },
+
+ hasChanges : function(){
+ return !_.isEqual(this.state.brew, this.savedBrew);
+ },
+
+ trySave : function(){
+ if(!this.debounceSave) this.debounceSave = _.debounce(this.save, SAVE_TIMEOUT);
+ if(this.hasChanges()){
+ this.debounceSave();
+ } else {
+ this.debounceSave.cancel();
+ }
+ },
+
+ handleGoogleClick : function(){
+ if(!global.account?.googleId) {
+ this.setState({
+ alertLoginToTransfer : true
+ });
+ return;
+ }
+ this.setState((prevState)=>({
+ confirmGoogleTransfer : !prevState.confirmGoogleTransfer
+ }));
+ this.clearErrors();
+ },
+
+ closeAlerts : function(event){
+ event.stopPropagation(); //Only handle click once so alert doesn't reopen
+ this.setState({
+ alertTrashedGoogleBrew : false,
+ alertLoginToTransfer : false,
+ confirmGoogleTransfer : false
+ });
+ },
+
+ toggleGoogleStorage : function(){
+ this.setState((prevState)=>({
+ saveGoogle : !prevState.saveGoogle,
+ isSaving : false,
+ errors : null
+ }), ()=>this.save());
+ },
+
+ clearErrors : function(){
+ this.setState({
+ errors : null,
+ isSaving : false
+
+ });
+ },
+
+ save : async function(){
+ if(this.debounceSave && this.debounceSave.cancel) this.debounceSave.cancel();
+
+ this.setState((prevState)=>({
+ isSaving : true,
+ errors : null,
+ htmlErrors : Markdown.validate(prevState.brew.text)
+ }));
+
+ const transfer = this.state.saveGoogle == _.isNil(this.state.brew.googleId);
+
+ const brew = this.state.brew;
+ brew.pageCount = ((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1;
+
+ if(this.state.saveGoogle) {
+ if(transfer) {
+ const res = await request
+ .post('/api/newGoogle/')
+ .send(brew)
+ .catch((err)=>{
+ console.log(err.status === 401
+ ? 'Not signed in!'
+ : 'Error Transferring to Google!');
+ this.setState({ errors: err, saveGoogle: false });
+ });
+
+ if(!res) { return; }
+
+ console.log('Deleting Local Copy');
+ await request.delete(`/api/${brew.editId}`)
+ .send()
+ .catch((err)=>{
+ console.log('Error deleting Local Copy');
+ });
+
+ this.savedBrew = res.body;
+ history.replaceState(null, null, `/edit/${this.savedBrew.googleId}${this.savedBrew.editId}`); //update URL to match doc ID
+ } else {
+ const res = await request
+ .put(`/api/updateGoogle/${brew.editId}`)
+ .send(brew)
+ .catch((err)=>{
+ console.log(err.status === 401
+ ? 'Not signed in!'
+ : 'Error Saving to Google!');
+ this.setState({ errors: err });
+ return;
+ });
+
+ this.savedBrew = res.body;
+ }
+ } else {
+ if(transfer) {
+ const res = await request.post('/api')
+ .send(brew)
+ .catch((err)=>{
+ console.log('Error creating Local Copy');
+ this.setState({ errors: err });
+ return;
+ });
+
+ await request.get(`/api/removeGoogle/${brew.googleId}${brew.editId}`)
+ .send()
+ .catch((err)=>{
+ console.log('Error Deleting Google Brew');
+ });
+
+ this.savedBrew = res.body;
+ history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); //update URL to match doc ID
+ } else {
+ const res = await request
+ .put(`/api/update/${brew.editId}`)
+ .send(brew)
+ .catch((err)=>{
+ console.log('Error Updating Local Brew');
+ this.setState({ errors: err });
+ return;
+ });
+
+ this.savedBrew = res.body;
+ }
+ }
+
+ this.setState((prevState)=>({
+ brew : _.merge({}, prevState.brew, {
+ googleId : this.savedBrew.googleId ? this.savedBrew.googleId : null,
+ editId : this.savedBrew.editId,
+ shareId : this.savedBrew.shareId
+ }),
+ isPending : false,
+ isSaving : false,
+ }));
+ },
+
+ renderGoogleDriveIcon : function(){
+ return
+ {this.state.saveGoogle
+ ?
+ :
+ }
+
+ {this.state.confirmGoogleTransfer &&
+
+ { this.state.saveGoogle
+ ? `Would you like to transfer this brew from your Google Drive storage back to the Homebrewery?`
+ : `Would you like to transfer this brew from the Homebrewery to your personal Google Drive storage?`
+ }
+
+
+ Yes
+
+
+ No
+
+
+ }
+
+ {this.state.alertLoginToTransfer &&
+
+ You must be signed in to a Google account to transfer
+ between the homebrewery and Google Drive!
+
+
+ Sign In
+
+
+
+ Not Now
+
+
+ }
+ ;
+ },
+
+ renderSaveButton : function(){
+ if(this.state.errors){
+ let errMsg = '';
+ try {
+ errMsg += `${this.state.errors.toString()}\n\n`;
+ errMsg += `\`\`\`\n${this.state.errors.stack}\n`;
+ errMsg += `${JSON.stringify(this.state.errors.response.error, null, ' ')}\n\`\`\``;
+ console.log(errMsg);
+ } catch (e){}
+
+ if(this.state.errors.status == '401'){
+ return
+ Oops!
+
+ You must be signed in to a Google account
+ to save this to
Google Drive!
+
+
+ Sign In
+
+
+
+ Not Now
+
+
+ ;
+ }
+
+ if(this.state.errors.status == '403' && this.state.errors.response.body.errors[0].reason == 'insufficientPermissions'){
+ return
+ Oops!
+
+ Looks like your Google credentials have
+ expired! Visit the log in page to sign out
+ and sign back in with Google
+ to save this to Google Drive!
+
+
+ Sign In
+
+
+
+ Not Now
+
+
+ ;
+ }
+
+ return
+ Oops!
+
+ Looks like there was a problem saving.
+ Report the issue
+ here
+ .
+
+ ;
+ }
+
+ if(this.state.isSaving){
+ return saving...;
+ }
+ if(this.state.isPending && this.hasChanges()){
+ return Save Now;
+ }
+ if(!this.state.isPending && !this.state.isSaving){
+ return saved.;
+ }
+ },
+
+ processShareId : function() {
+ return this.state.brew.googleId ?
+ this.state.brew.googleId + this.state.brew.shareId :
+ this.state.brew.shareId;
+ },
+
+ getRedditLink : function(){
+
+ const shareLink = this.processShareId();
+ const systems = this.props.brew.systems.length > 0 ? ` [${this.props.brew.systems.join(' - ')}]` : '';
+ const title = `${this.props.brew.title} ${systems}`;
+ const text = `Hey guys! I've been working on this homebrew. I'd love your feedback. Check it out.
+
+**[Homebrewery Link](https://homebrewery.naturalcrit.com/share/${shareLink})**`;
+
+ return `https://www.reddit.com/r/UnearthedArcana/submit?title=${encodeURIComponent(title)}&text=${encodeURIComponent(text)}`;
+ },
+
+ renderNavbar : function(){
+ const shareLink = this.processShareId();
+
+ return
+
+ {this.state.alertTrashedGoogleBrew &&
+
+ This brew is currently in your Trash folder on Google Drive!
If you want to keep it, make sure to move it before it is deleted permanently!
+
+ OK
+
+
+ }
+
+
+ {this.state.brew.title}
+
+
+
+ {this.renderGoogleDriveIcon()}
+ {this.renderSaveButton()}
+
+
+
+
+ share
+
+
+ view
+
+ {navigator.clipboard.writeText(`https://homebrewery.naturalcrit.com/share/${shareLink}`);}}>
+ copy url
+
+
+ post to reddit
+
+
+
+
+
+
+
+ ;
+ },
+
+ render : function(){
+ return
+
+ {this.renderNavbar()}
+
+
+
+
+
+
+
+
;
}
});
diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx
index 0e424a998..3f09cac4e 100644
--- a/client/homebrew/pages/newPage/newPage.jsx
+++ b/client/homebrew/pages/newPage/newPage.jsx
@@ -3,11 +3,20 @@ require('./newPage.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
-
-const EditorPage = require('../basePages/editorPage/editorPage.jsx');
+const request = require('superagent');
const Markdown = require('naturalcrit/markdown.js');
+const Nav = require('naturalcrit/nav/nav.jsx');
+const Navbar = require('../../navbar/navbar.jsx');
+const AccountNavItem = require('../../navbar/account.navitem.jsx');
+const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
+const IssueNavItem = require('../../navbar/issue.navitem.jsx');
+
+const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
+const Editor = require('../../editor/editor.jsx');
+const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
+
const BREWKEY = 'homebrewery-new';
const STYLEKEY = 'homebrewery-new-style';
const METAKEY = 'homebrewery-new-meta';
@@ -73,13 +82,238 @@ const NewPage = createClass({
};
},
- render : function(){
- const googleDriveOptions = [
- 'Set save location to the Homebrewery?',
- 'Set save location to your personal Google Drive storage?'
- ];
+ componentDidMount : function() {
+ document.addEventListener('keydown', this.handleControlKeys);
+ },
+ componentWillUnmount : function() {
+ document.removeEventListener('keydown', this.handleControlKeys);
+ },
- return ;
+ handleControlKeys : function(e){
+ if(!(e.ctrlKey || e.metaKey)) return;
+ const S_KEY = 83;
+ const P_KEY = 80;
+ if(e.keyCode == S_KEY) this.save();
+ if(e.keyCode == P_KEY) this.print();
+ if(e.keyCode == P_KEY || e.keyCode == S_KEY){
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ },
+
+ handleSplitMove : function(){
+ this.refs.editor.update();
+ },
+
+ handleTextChange : function(text){
+ //If there are errors, run the validator on every change to give quick feedback
+ let htmlErrors = this.state.htmlErrors;
+ if(htmlErrors.length) htmlErrors = Markdown.validate(text);
+
+ this.setState((prevState)=>({
+ brew : _.merge({}, prevState.brew, { text: text }),
+ htmlErrors : htmlErrors
+ }));
+ localStorage.setItem(BREWKEY, text);
+ },
+
+ handleStyleChange : function(style){
+ this.setState((prevState)=>({
+ brew : _.merge({}, prevState.brew, { style: style }),
+ }));
+ localStorage.setItem(STYLEKEY, style);
+ },
+
+ handleMetaChange : function(metadata){
+ this.setState((prevState)=>({
+ brew : _.merge({}, prevState.brew, metadata),
+ }));
+ localStorage.setItem(METAKEY, JSON.stringify({
+ // 'title' : this.state.brew.title,
+ // 'description' : this.state.brew.description,
+ 'renderer' : this.state.brew.renderer
+ }));
+ },
+
+ clearErrors : function(){
+ this.setState({
+ errors : null,
+ isSaving : false
+
+ });
+ },
+
+ save : async function(){
+ this.setState({
+ isSaving : true
+ });
+
+ 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);
+ };
+
+ brew.pageCount=((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1;
+
+ if(this.state.saveGoogle) {
+ const res = await request
+ .post('/api/newGoogle/')
+ .send(brew)
+ .catch((err)=>{
+ console.log(err.status === 401
+ ? 'Not signed in!'
+ : 'Error Creating New Google Brew!');
+ this.setState({ isSaving: false, errors: err });
+ return;
+ });
+
+ brew = res.body;
+ localStorage.removeItem(BREWKEY);
+ localStorage.removeItem(STYLEKEY);
+ localStorage.removeItem(METAKEY);
+ window.location = `/edit/${brew.googleId}${brew.editId}`;
+ } else {
+ request.post('/api')
+ .send(brew)
+ .end((err, res)=>{
+ if(err){
+ this.setState({
+ isSaving : false
+ });
+ return;
+ }
+ window.onbeforeunload = function(){};
+ brew = res.body;
+ localStorage.removeItem(BREWKEY);
+ localStorage.removeItem(STYLEKEY);
+ localStorage.removeItem(METAKEY);
+ window.location = `/edit/${brew.editId}`;
+ });
+ }
+ },
+
+ renderSaveButton : function(){
+ if(this.state.errors){
+ let errMsg = '';
+ try {
+ errMsg += `${this.state.errors.toString()}\n\n`;
+ errMsg += `\`\`\`\n${this.state.errors.stack}\n`;
+ errMsg += `${JSON.stringify(this.state.errors.response.error, null, ' ')}\n\`\`\``;
+ console.log(errMsg);
+ } catch (e){}
+
+ if(this.state.errors.status == '401'){
+ return
+ Oops!
+
+ You must be signed in to a Google account
+ to save this to
Google Drive!
+
+
+ Sign In
+
+
+
+ Not Now
+
+
+ ;
+ }
+
+ if(this.state.errors.status == '403' && this.state.errors.response.body.errors[0].reason == 'insufficientPermissions'){
+ return
+ Oops!
+
+ Looks like your Google credentials have
+ expired! Visit the log in page to sign out
+ and sign back in with Google
+ to save this to Google Drive!
+
+
+ Sign In
+
+
+
+ Not Now
+
+
+ ;
+ }
+
+ return
+ Oops!
+
+ Looks like there was a problem saving.
+ Report the issue
+ here
+ .
+
+ ;
+ }
+
+ if(this.state.isSaving){
+ return
+ save...
+ ;
+ } else {
+ return
+ save
+ ;
+ }
+ },
+
+ print : function(){
+ window.open('/print?dialog=true&local=print', '_blank');
+ },
+
+ renderLocalPrintButton : function(){
+ return
+ get PDF
+ ;
+ },
+
+ renderNavbar : function(){
+ return
+
+
+ {this.state.brew.title}
+
+
+
+ {this.renderSaveButton()}
+ {this.renderLocalPrintButton()}
+
+
+
+
+ ;
+ },
+
+ render : function(){
+ return
+ {this.renderNavbar()}
+
+
+
+
+
+
+
;
}
});