From eca12aae824090ad3f20590e4d8897d45ff5b4db Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Fri, 31 Dec 2021 13:06:21 +1300 Subject: [PATCH] Rebase on `master` --- .../pages/basePages/editorPage/editorPage.jsx | 578 ------------------ .../basePages/editorPage/editorPage.less | 99 --- client/homebrew/pages/editPage/editPage.jsx | 1 + client/homebrew/pages/newPage/newPage.jsx | 1 + 4 files changed, 2 insertions(+), 677 deletions(-) delete mode 100644 client/homebrew/pages/basePages/editorPage/editorPage.jsx delete mode 100644 client/homebrew/pages/basePages/editorPage/editorPage.less 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 - ? googleDriveActive - : googleDriveInactive - } - - {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 d2f21481d..fc378845e 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -351,6 +351,7 @@ const EditPage = createClass({ } if(this.state.errors.response.req.url.match(/^\/api\/.*Google.*$/m)){ + if(this.state.errors.status == '403' && this.state.errors.response.body.errors[0].reason == 'insufficientPermissions'){ return Oops!
diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 0c6b0aa6a..4f112c703 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -228,6 +228,7 @@ const NewPage = createClass({ } if(this.state.errors.response.req.url.match(/^\/api\/.*Google.*$/m)){ + if(this.state.errors.status == '403' && this.state.errors.response.body.errors[0].reason == 'insufficientPermissions'){ return Oops!