From aa6f62486c1547c66661541c081116c005dbe6af Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 1 Oct 2026 20:15:10 +0000 Subject: [PATCH 1/2] Move "loadBrewFromLocalstorage" to common hook. Add an "onSaveSuccess()" function pages can pass in. --- client/homebrew/pages/editPage/editPage.jsx | 24 +++---- client/homebrew/pages/homePage/homePage.jsx | 27 ++++---- client/homebrew/pages/newPage/newPage.jsx | 62 +++-------------- .../utils/commonEditPageFunctions.jsx | 68 +++++++++++++++---- 4 files changed, 87 insertions(+), 94 deletions(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index f5ca38748..e29a81caa 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 = { @@ -123,8 +118,10 @@ const EditPage = (props)=>{ ...prevBrew, ...updatedFields })); + }; - history.replaceState(null, null, `/edit/${res.body.editId}`); + const onSaveSuccess = (savedBrew)=>{ + history.replaceState(null, null, `/edit/${savedBrew.editId}`);; }; const renderGoogleDriveIcon = ()=>( @@ -176,24 +173,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..9b9880197 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 = { @@ -44,32 +38,35 @@ const HomePage =(props)=>{ }); if(!res) return; - const saved = res.body; + setCurrentBrew((prevBrew)=>({ + ...prevBrew, + ...updatedFields + })); + }; + + 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..39a9bdcbd 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 = { @@ -36,39 +28,6 @@ const NewPage = (props)=>{ 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,13 @@ const NewPage = (props)=>{ }); if(!res) return; - const savedBrew = res.body; + setCurrentBrew((prevBrew)=>({ + ...prevBrew, + ...updatedFields + })); + }; - localStorage.removeItem(BREWKEY); - localStorage.removeItem(STYLEKEY); - localStorage.removeItem(METAKEY); + const onSaveSuccess = (savedBrew)=>{ window.onbeforeunload = null; window.location = `/edit/${savedBrew.editId}`; }; @@ -100,23 +61,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..db17ac77e 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 })); } }; @@ -165,6 +207,8 @@ export default function useCommonEditPageFunctions(dependencies) { setIsSaving(false); setLastSavedTime(new Date()); if(!autoSaveEnabled) resetWarnUnsavedTimer(); + if(useLocalStorage) clearLocalStorage(); + onSaveSuccess(); }, newTimeout); }); @@ -216,14 +260,14 @@ export default function useCommonEditPageFunctions(dependencies) { ? : {renderSaveButton()} - {pageName == "editPage" && renderAutoSaveButton()} + {pageName == 'editPage' && renderAutoSaveButton()} } - {(pageName == "editPage") && } - + {(pageName == 'editPage') && } + From 531d9343b308f4e18de7becded8913da39657f70 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 1 Oct 2026 20:28:53 +0000 Subject: [PATCH 2/2] Small fixes --- client/homebrew/pages/editPage/editPage.jsx | 4 +++- client/homebrew/pages/homePage/homePage.jsx | 4 +++- client/homebrew/pages/newPage/newPage.jsx | 4 +++- client/homebrew/utils/commonEditPageFunctions.jsx | 8 +++++--- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index e29a81caa..351ad8e71 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -21,7 +21,7 @@ import { updateHistory, versionHistoryGarbageCollection } from '../../utils/vers import googleDriveIcon from '../../googleDrive.svg'; const useLocalStorage = false; -const sandbox = false; +const sandbox = false; const showFloatingButtons = false; const showEditorButtons = true; const pageName = 'editPage'; @@ -118,6 +118,8 @@ const EditPage = (props)=>{ ...prevBrew, ...updatedFields })); + + return res.body; }; const onSaveSuccess = (savedBrew)=>{ diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 9b9880197..b430a7ed5 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -40,8 +40,10 @@ const HomePage =(props)=>{ setCurrentBrew((prevBrew)=>({ ...prevBrew, - ...updatedFields + ...res.body })); + + return res.body; }; const onSaveSuccess = (savedBrew)=>{ diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 39a9bdcbd..ea389faa4 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -48,8 +48,10 @@ const NewPage = (props)=>{ setCurrentBrew((prevBrew)=>({ ...prevBrew, - ...updatedFields + ...res.body })); + + return res.body; }; const onSaveSuccess = (savedBrew)=>{ diff --git a/client/homebrew/utils/commonEditPageFunctions.jsx b/client/homebrew/utils/commonEditPageFunctions.jsx index db17ac77e..aa55e5394 100644 --- a/client/homebrew/utils/commonEditPageFunctions.jsx +++ b/client/homebrew/utils/commonEditPageFunctions.jsx @@ -202,13 +202,15 @@ export default function useCommonEditPageFunctions(dependencies) { setIsSaving(true); setError(null); setHTMLErrors(hbfm.validate(currentBrew.text)); - await save(currentBrew, saveToGoogle) + let savedBrew = await save(currentBrew, saveToGoogle) .catch((err)=>{setError(err);}); + if(savedBrew) { + if(useLocalStorage) clearLocalStorage(); + onSaveSuccess(savedBrew); + } setIsSaving(false); setLastSavedTime(new Date()); if(!autoSaveEnabled) resetWarnUnsavedTimer(); - if(useLocalStorage) clearLocalStorage(); - onSaveSuccess(); }, newTimeout); });