diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less index a29fff32a..5f37d74a1 100644 --- a/client/homebrew/navbar/navbar.less +++ b/client/homebrew/navbar/navbar.less @@ -55,6 +55,18 @@ text-align : center; text-transform : initial; } + .save-menu { + .dropdown { + z-index: 1000; + } + .navItem i.fa-power-off { + color : red; + &.active { + color : rgb(0, 182, 52); + filter : drop-shadow(0 0 2px rgba(0, 182, 52, 0.765)) + } + } + } .patreon.navItem{ border-left : 1px solid #666; border-right : 1px solid #666; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index d6a20527e..3608c277d 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -62,7 +62,10 @@ const EditPage = createClass({ confirmGoogleTransfer : false, errors : null, htmlErrors : Markdown.validate(this.props.brew.text), - url : '' + url : '', + autoSave : true, + autoSaveWarning : false, + unsavedTime : new Date() }; }, savedBrew : null, @@ -72,9 +75,17 @@ const EditPage = createClass({ url : window.location.href }); + this.savedBrew = JSON.parse(JSON.stringify(this.props.brew)); //Deep copy - this.trySave(); + this.setState({ autoSave: JSON.parse(localStorage.getItem('AUTOSAVE_ON')) }, ()=>{ + if(this.state.autoSave){ + this.trySave(); + } else { + this.setState({ autoSaveWarning: true }); + } + }); + window.onbeforeunload = ()=>{ if(this.state.isSaving || this.state.isPending){ return 'You have unsaved changes!'; @@ -117,14 +128,14 @@ const EditPage = createClass({ brew : { ...prevState.brew, text: text }, isPending : true, htmlErrors : htmlErrors - }), ()=>this.trySave()); + }), ()=>{if(this.state.autoSave) this.trySave();}); }, handleStyleChange : function(style){ this.setState((prevState)=>({ brew : { ...prevState.brew, style: style }, isPending : true - }), ()=>this.trySave()); + }), ()=>{if(this.state.autoSave) this.trySave();}); }, handleMetaChange : function(metadata){ @@ -134,7 +145,7 @@ const EditPage = createClass({ ...metadata }, isPending : true, - }), ()=>this.trySave()); + }), ()=>{if(this.state.autoSave) this.trySave();}); }, @@ -221,8 +232,9 @@ const EditPage = createClass({ editId : this.savedBrew.editId, shareId : this.savedBrew.shareId }, - isPending : false, - isSaving : false, + isPending : false, + isSaving : false, + unsavedTime : new Date() })); }, @@ -329,17 +341,55 @@ const EditPage = createClass({ ; } + if(this.state.autoSaveWarning && this.hasChanges()){ + this.setAutosaveWarning(); + const elapsedTime = Math.round((new Date() - this.state.unsavedTime) / 1000 / 60); + const text = elapsedTime == 0 ? 'Autosave is OFF.' : `Autosave is OFF, and you haven't saved for ${elapsedTime} minutes.`; + + return + Reminder... +
+ {text} +
+
; + } + if(this.state.isSaving){ return saving...; } if(this.state.isPending && this.hasChanges()){ return Save Now; } + if(!this.state.isPending && !this.state.isSaving && this.state.autoSave){ + return auto-saved.; + } if(!this.state.isPending && !this.state.isSaving){ return saved.; } }, + handleAutoSave : function(){ + if(this.warningTimer) clearTimeout(this.warningTimer); + this.setState((prevState)=>({ + autoSave : !prevState.autoSave, + autoSaveWarning : prevState.autoSave + }), ()=>{ + localStorage.setItem('AUTOSAVE_ON', JSON.stringify(this.state.autoSave)); + }); + }, + + setAutosaveWarning : function(){ + setTimeout(()=>this.setState({ autoSaveWarning: false }), 4000); // 4 seconds to display + this.warningTimer = setTimeout(()=>{this.setState({ autoSaveWarning: true });}, 900000); // 15 minutes between warnings + this.warningTimer; + }, + + renderAutoSaveButton : function(){ + return + Autosave + ; + }, + processShareId : function() { return this.state.brew.googleId && !this.state.brew.stubbed ? this.state.brew.googleId + this.state.brew.shareId : @@ -378,7 +428,10 @@ const EditPage = createClass({ {this.renderGoogleDriveIcon()} - {this.renderSaveButton()} + + {this.renderSaveButton()} + {this.renderAutoSaveButton()} + diff --git a/client/homebrew/pages/editPage/editPage.less b/client/homebrew/pages/editPage/editPage.less index 5d0d21b64..9d3f69221 100644 --- a/client/homebrew/pages/editPage/editPage.less +++ b/client/homebrew/pages/editPage/editPage.less @@ -32,7 +32,7 @@ position : absolute; top : 100%; left : 50%; - z-index : 100000; + z-index : 500; width : 140px; padding : 3px; color : white;