diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index f5ca38748..71dfdbdf2 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -3,7 +3,7 @@ import './editPage.less'; // Common imports import React, { useState, useEffect, useRef, useEffectEvent } from 'react'; import request from '../../utils/request-middleware.js'; -import { hbfm } from 'marked-hbfm'; + import _ from 'lodash'; import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js'; @@ -20,16 +20,11 @@ import { makePatches, stringifyPatches } from '@sanity/diff-match-patch'; import { updateHistory, versionHistoryGarbageCollection } from '../../utils/versionHistory.js'; import googleDriveIcon from '../../googleDrive.svg'; -const BREWKEY = 'HB_newPage_content'; -const STYLEKEY = 'HB_newPage_style'; -const SNIPKEY = 'HB_newPage_snippets'; -const METAKEY = 'HB_newPage_meta'; - const useLocalStorage = false; -const sandbox = false; +const sandbox = false; const showFloatingButtons = false; const showEditorButtons = true; -const pageName = "editPage"; +const pageName = 'editPage'; const EditPage = (props)=>{ props = { @@ -108,23 +103,17 @@ const EditPage = (props)=>{ if(!res) return; const updatedFields = { - googleId : res.body.googleId ?? null, - editId : res.body.editId, + googleId : res.body.googleId ?? null, //TODO: investigate if we can set googleId:null in server/update instead of undefined + editId : res.body.editId, //then, editPage can just apply res.body instead of breaking out these fields. shareId : res.body.shareId, version : res.body.version }; - lastSavedBrew.current = { - ...brew, - ...updatedFields - }; + return updatedFields; + }; - setCurrentBrew((prevBrew)=>({ - ...prevBrew, - ...updatedFields - })); - - history.replaceState(null, null, `/edit/${res.body.editId}`); + const onSaveSuccess = (savedBrew)=>{ + history.replaceState(null, null, `/edit/${savedBrew.editId}`);; }; const renderGoogleDriveIcon = ()=>( @@ -176,24 +165,21 @@ const EditPage = (props)=>{ trySave, } = useCommonEditPageFunctions({ saveGoogle, + setSaveGoogle, error, setError, currentBrew, setCurrentBrew, useLocalStorage, - BREWKEY, - STYLEKEY, - SNIPKEY, - METAKEY, - hbfm, sandbox, showFloatingButtons, lastSavedBrew, save, + onSaveSuccess, pageName, showEditorButtons, renderGoogleDriveIcon, - userThemes: props.userThemes + userThemes : props.userThemes }); return renderPanels(); diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 3a0590889..20b75b486 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -3,7 +3,6 @@ import './homePage.less'; // Common imports import React, { useState, useEffect, useRef, useEffectEvent } from 'react'; import request from '../../utils/request-middleware.js'; -import { hbfm } from 'marked-hbfm'; import _ from 'lodash'; import { DEFAULT_BREW } from '../../../../server/brewDefaults.js'; @@ -11,16 +10,11 @@ import { DEFAULT_BREW } from '../../../../server/brewDefau import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.jsx'; // Page specific imports -const BREWKEY = 'HB_newPage_content'; -const STYLEKEY = 'HB_newPage_style'; -const SNIPKEY = 'HB_newPage_snippets'; -const METAKEY = 'HB_newPage_meta'; - const useLocalStorage = false; const sandbox = true; const showFloatingButtons = true; const showEditorButtons = false; -const pageName = "homePage"; +const pageName = 'homePage'; const HomePage =(props)=>{ props = { @@ -28,9 +22,9 @@ const HomePage =(props)=>{ ...props }; - const [currentBrew, setCurrentBrew] = useState(props.brew); - const [saveGoogle, setSaveGoogle] = useState(global.account?.googleId ? true : false); - const [error, setError] = useState(undefined); + const [currentBrew, setCurrentBrew] = useState(props.brew); + const [saveGoogle, setSaveGoogle] = useState(global.account?.googleId ? true : false); + const [error, setError] = useState(undefined); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); @@ -44,32 +38,32 @@ const HomePage =(props)=>{ }); if(!res) return; - const saved = res.body; + return res.body; + }; + + const onSaveSuccess = (savedBrew)=>{ window.onbeforeunload = null; - window.location = `/edit/${saved.editId}`; + window.location = `/edit/${savedBrew.editId}`; }; const { renderPanels } = useCommonEditPageFunctions({ saveGoogle, + setSaveGoogle, error, setError, currentBrew, setCurrentBrew, useLocalStorage, - BREWKEY, - STYLEKEY, - SNIPKEY, - METAKEY, - hbfm, sandbox, showFloatingButtons, lastSavedBrew, save, + onSaveSuccess, pageName, showEditorButtons, - userThemes: {} + userThemes : {} }); return renderPanels(); diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 951b0a4e0..8606cc752 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -3,7 +3,6 @@ import './newPage.less'; // Common imports import React, { useState, useEffect, useRef, useEffectEvent } from 'react'; import request from '../../utils/request-middleware.js'; -import { hbfm } from 'marked-hbfm'; import _ from 'lodash'; import { DEFAULT_BREW } from '../../../../server/brewDefaults.js'; @@ -11,18 +10,11 @@ import { DEFAULT_BREW } from '../../../../server/brewDefau import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.jsx'; // Page specific imports -const BREWKEY = 'HB_newPage_content'; -const STYLEKEY = 'HB_newPage_style'; -const SNIPKEY = 'HB_newPage_snippets'; -const METAKEY = 'HB_newPage_meta'; - -const SAVEKEYPREFIX = 'HB_editor_defaultSave_'; - const useLocalStorage = true; const sandbox = true; const showFloatingButtons = false; const showEditorButtons = true; -const pageName = "newPage"; +const pageName = 'newPage'; const NewPage = (props)=>{ props = { @@ -31,44 +23,11 @@ const NewPage = (props)=>{ }; const [currentBrew, setCurrentBrew] = useState(props.brew); - const [saveGoogle, setSaveGoogle] = useState(global.account?.googleId ? true : false); - const [error, setError] = useState(null); + const [saveGoogle, setSaveGoogle] = useState(global.account?.googleId ? true : false); + const [error, setError] = useState(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); - useEffect(()=>{ - loadBrew(); - }, []); - - const loadBrew = ()=>{ - const brew = { ...currentBrew }; - if(!brew.shareId && typeof window !== 'undefined') { //Load from localStorage if in client browser - const brewStorage = localStorage.getItem(BREWKEY); - const styleStorage = localStorage.getItem(STYLEKEY); - const metaStorage = JSON.parse(localStorage.getItem(METAKEY)); - - brew.text = brewStorage ?? brew.text; - brew.style = styleStorage ?? brew.style; - brew.renderer = metaStorage?.renderer ?? brew.renderer; - brew.theme = metaStorage?.theme ?? brew.theme; - brew.lang = metaStorage?.lang ?? brew.lang; - } - - const SAVEKEY = `${SAVEKEYPREFIX}${global.account?.username}`; - const saveStorage = localStorage.getItem(SAVEKEY) || 'HOMEBREWERY'; - - setCurrentBrew(brew); - lastSavedBrew.current = brew; - setSaveGoogle(saveStorage == 'GOOGLE-DRIVE' && saveGoogle); - - localStorage.setItem(BREWKEY, brew.text); - if(brew.style) - localStorage.setItem(STYLEKEY, brew.style); - localStorage.setItem(METAKEY, JSON.stringify({ renderer: brew.renderer, theme: brew.theme, lang: brew.lang })); - if(window.location.pathname !== '/new') - window.history.replaceState({}, window.location.title, '/new/'); - }; - const save = async (brew, saveToGoogle)=>{ //Prepare content to send to server const brewToSave = { @@ -87,11 +46,10 @@ const NewPage = (props)=>{ }); if(!res) return; - const savedBrew = res.body; + return res.body; + }; - localStorage.removeItem(BREWKEY); - localStorage.removeItem(STYLEKEY); - localStorage.removeItem(METAKEY); + const onSaveSuccess = (savedBrew)=>{ window.onbeforeunload = null; window.location = `/edit/${savedBrew.editId}`; }; @@ -100,23 +58,20 @@ const NewPage = (props)=>{ renderPanels } = useCommonEditPageFunctions({ saveGoogle, + setSaveGoogle, error, setError, currentBrew, setCurrentBrew, useLocalStorage, - BREWKEY, - STYLEKEY, - SNIPKEY, - METAKEY, - hbfm, sandbox, showFloatingButtons, lastSavedBrew, save, + onSaveSuccess, pageName, showEditorButtons, - userThemes: props.userThemes + userThemes : props.userThemes }); return renderPanels(); diff --git a/client/homebrew/utils/commonEditPageFunctions.jsx b/client/homebrew/utils/commonEditPageFunctions.jsx index f92bf9b4d..701680ecf 100644 --- a/client/homebrew/utils/commonEditPageFunctions.jsx +++ b/client/homebrew/utils/commonEditPageFunctions.jsx @@ -1,6 +1,7 @@ import React, { useState, useEffect, useEffectEvent, useRef } from 'react'; import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; import _ from 'lodash'; +import { hbfm } from 'marked-hbfm'; import Headtags from '@vitreum/headtags.js'; import SplitPane from '@components/splitPane/splitPane.jsx'; @@ -22,7 +23,12 @@ import ShareNavItem from '@navbar/share.navitem.jsx'; import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; -const AUTOSAVE_KEY = 'HB_editor_autoSaveOn'; +const AUTOSAVE_KEY = 'HB_editor_autoSaveOn'; +const BREWKEY = 'HB_newPage_content'; +const STYLEKEY = 'HB_newPage_style'; +const SNIPKEY = 'HB_newPage_snippets'; +const METAKEY = 'HB_newPage_meta'; +const SAVEKEY_PREFIX = 'HB_editor_defaultSave_'; const SAVE_TIMEOUT = 10000; //Autosave 10 seconds after last change const UNSAVED_WARNING_TIMEOUT = 900000; //Warn user afer 15 minutes of unsaved changes @@ -31,20 +37,17 @@ const UNSAVED_WARNING_POPUP_TIMEOUT = 4000; //Show the warning for 4 seconds export default function useCommonEditPageFunctions(dependencies) { const { saveGoogle, + setSaveGoogle, error, setError, currentBrew, setCurrentBrew, useLocalStorage, - BREWKEY, - STYLEKEY, - SNIPKEY, - METAKEY, - hbfm, sandbox, showFloatingButtons, lastSavedBrew, save, + onSaveSuccess, pageName, renderGoogleDriveIcon = ()=>{}, showEditorButtons, @@ -70,6 +73,7 @@ export default function useCommonEditPageFunctions(dependencies) { //==--------- Page setup ----------==// useEffect(()=>{ + if(useLocalStorage) loadBrewFromLocalStorage(); const autoSavePref = !sandbox && JSON.parse(localStorage.getItem(AUTOSAVE_KEY) ?? true); setAutoSaveEnabled(autoSavePref); setWarnUnsavedChanges(!autoSavePref); @@ -95,6 +99,44 @@ export default function useCommonEditPageFunctions(dependencies) { }; }, []); + const loadBrewFromLocalStorage = ()=>{ + const brew = { ...currentBrew }; + if(!brew.shareId && typeof window !== 'undefined') { //Load from localStorage if in client browser + const brewStorage = localStorage.getItem(BREWKEY); + const styleStorage = localStorage.getItem(STYLEKEY); + const snipStorage = localStorage.getItem(SNIPKEY); + const metaStorage = JSON.parse(localStorage.getItem(METAKEY)); + + brew.text = brewStorage ?? brew.text; + brew.style = styleStorage ?? brew.style; + brew.snippets = snipStorage ?? brew.snippets; + brew.renderer = metaStorage?.renderer ?? brew.renderer; + brew.theme = metaStorage?.theme ?? brew.theme; + brew.lang = metaStorage?.lang ?? brew.lang; + } + + const SAVEKEY = `${SAVEKEY_PREFIX}${global.account?.username}`; + const saveStorage = localStorage.getItem(SAVEKEY) || 'HOMEBREWERY'; + + setCurrentBrew(brew); + lastSavedBrew.current = brew; + setSaveGoogle(saveStorage == 'GOOGLE-DRIVE' && saveGoogle); + + localStorage.setItem(BREWKEY, brew.text); + if(brew.style) localStorage.setItem(STYLEKEY, brew.style); + if(brew.snippets) localStorage.setItem(SNIPKEY, brew.snippets); + localStorage.setItem(METAKEY, JSON.stringify({ renderer: brew.renderer, theme: brew.theme, lang: brew.lang })); + if(window.location.pathname !== '/new') + window.history.replaceState({}, window.location.title, '/new/'); + }; + + const clearLocalStorage = ()=>{ + localStorage.removeItem(BREWKEY); + localStorage.removeItem(STYLEKEY); + localStorage.removeItem(SNIPKEY); + localStorage.removeItem(METAKEY); + }; + //======----- Check for unsaved changes and autosave if enabled -----====== useEffect(()=>{ const hasChange = !_.isEqual(currentBrew, lastSavedBrew.current); @@ -127,12 +169,12 @@ export default function useCommonEditPageFunctions(dependencies) { if(useLocalStorage) { if(field == 'text') localStorage.setItem(BREWKEY, value); - if(field == 'style') localStorage.setItem(STYLEKEY, value); + if(field == 'style') localStorage.setItem(STYLEKEY, value); if(field == 'snippets') localStorage.setItem(SNIPKEY, value); if(field == 'metadata') localStorage.setItem(METAKEY, JSON.stringify({ renderer : value.renderer, - theme : value.theme, - lang : value.lang + theme : value.theme, + lang : value.lang })); } }; @@ -160,8 +202,23 @@ export default function useCommonEditPageFunctions(dependencies) { setIsSaving(true); setError(null); setHTMLErrors(hbfm.validate(currentBrew.text)); - await save(currentBrew, saveToGoogle) + const brewToSave = currentBrew; + let savedBrew = await save(brewToSave, saveToGoogle) .catch((err)=>{setError(err);}); + if(savedBrew) { + lastSavedBrew.current = { + ...brewToSave, + ...savedBrew + }; + + setCurrentBrew((prevBrew)=>({ + ...prevBrew, + ...savedBrew + })); + + if(useLocalStorage) clearLocalStorage(); + onSaveSuccess(savedBrew); + } setIsSaving(false); setLastSavedTime(new Date()); if(!autoSaveEnabled) resetWarnUnsavedTimer(); @@ -216,14 +273,14 @@ export default function useCommonEditPageFunctions(dependencies) { ? : {renderSaveButton()} - {pageName == "editPage" && renderAutoSaveButton()} + {pageName == 'editPage' && renderAutoSaveButton()} } - {(pageName == "editPage") && } - + {(pageName == 'editPage') && } +