mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-09-20 14:32:57 +00:00
Extract common "handlePageChange" to a reusable hook
This commit is contained in:
@@ -10,18 +10,20 @@ import _ from 'lodash';
|
|||||||
import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js';
|
import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js';
|
||||||
import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js';
|
import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js';
|
||||||
|
|
||||||
|
import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.js'
|
||||||
|
|
||||||
import SplitPane from '@components/splitPane/splitPane.jsx';
|
import SplitPane from '@components/splitPane/splitPane.jsx';
|
||||||
import Editor from '../../editor/editor.jsx';
|
import Editor from '../../editor/editor.jsx';
|
||||||
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
||||||
|
|
||||||
import Nav from '@navbar/nav.jsx';
|
import Nav from '@navbar/nav.jsx';
|
||||||
import Navbar from '@navbar/navbar.jsx';
|
import Navbar from '@navbar/navbar.jsx';
|
||||||
import NewBrewItem from '@navbar/newbrew.navitem.jsx';
|
import NewBrewItem from '@navbar/newbrew.navitem.jsx';
|
||||||
import AccountNavItem from '@navbar/account.navitem.jsx';
|
import AccountNavItem from '@navbar/account.navitem.jsx';
|
||||||
import ErrorNavItem from '@navbar/error-navitem.jsx';
|
import ErrorNavItem from '@navbar/error-navitem.jsx';
|
||||||
import HelpNavItem from '@navbar/help.navitem.jsx';
|
import HelpNavItem from '@navbar/help.navitem.jsx';
|
||||||
import VaultNavItem from '@navbar/vault.navitem.jsx';
|
import VaultNavItem from '@navbar/vault.navitem.jsx';
|
||||||
import PrintNavItem from '@navbar/print.navitem.jsx';
|
import PrintNavItem from '@navbar/print.navitem.jsx';
|
||||||
import RecentNavItems from '@navbar/recent.navitem.jsx';
|
import RecentNavItems from '@navbar/recent.navitem.jsx';
|
||||||
const { both: RecentNavItem } = RecentNavItems;
|
const { both: RecentNavItem } = RecentNavItems;
|
||||||
|
|
||||||
@@ -41,7 +43,6 @@ const SAVE_TIMEOUT = 10000;
|
|||||||
const UNSAVED_WARNING_TIMEOUT = 900000; //Warn user afer 15 minutes of unsaved changes
|
const UNSAVED_WARNING_TIMEOUT = 900000; //Warn user afer 15 minutes of unsaved changes
|
||||||
const UNSAVED_WARNING_POPUP_TIMEOUT = 4000; //Show the warning for 4 seconds
|
const UNSAVED_WARNING_POPUP_TIMEOUT = 4000; //Show the warning for 4 seconds
|
||||||
|
|
||||||
|
|
||||||
const AUTOSAVE_KEY = 'HB_editor_autoSaveOn';
|
const AUTOSAVE_KEY = 'HB_editor_autoSaveOn';
|
||||||
const BREWKEY = 'HB_newPage_content';
|
const BREWKEY = 'HB_newPage_content';
|
||||||
const STYLEKEY = 'HB_newPage_style';
|
const STYLEKEY = 'HB_newPage_style';
|
||||||
@@ -49,7 +50,7 @@ const SNIPKEY = 'HB_newPage_snippets';
|
|||||||
const METAKEY = 'HB_newPage_meta';
|
const METAKEY = 'HB_newPage_meta';
|
||||||
|
|
||||||
const useLocalStorage = false;
|
const useLocalStorage = false;
|
||||||
const neverSaved = false;
|
const neverSaved = false;
|
||||||
|
|
||||||
const EditPage = (props)=>{
|
const EditPage = (props)=>{
|
||||||
props = {
|
props = {
|
||||||
@@ -82,6 +83,23 @@ const EditPage = (props)=>{
|
|||||||
const trySaveRef = useRef(null); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew
|
const trySaveRef = useRef(null); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew
|
||||||
const unsavedChangesRef = useRef(unsavedChanges); // Similarly, onBeforeUnload lives outside React and needs ref to unsavedChanges
|
const unsavedChangesRef = useRef(unsavedChanges); // Similarly, onBeforeUnload lives outside React and needs ref to unsavedChanges
|
||||||
|
|
||||||
|
const {
|
||||||
|
handleBrewChange
|
||||||
|
} = useCommonEditPageFunctions({
|
||||||
|
setError,
|
||||||
|
setThemeBundle,
|
||||||
|
HTMLErrors,
|
||||||
|
setHTMLErrors,
|
||||||
|
setCurrentBrew,
|
||||||
|
useLocalStorage,
|
||||||
|
BREWKEY,
|
||||||
|
STYLEKEY,
|
||||||
|
SNIPKEY,
|
||||||
|
METAKEY,
|
||||||
|
fetchThemeBundle,
|
||||||
|
hbfm
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
const autoSavePref = JSON.parse(localStorage.getItem(AUTOSAVE_KEY) ?? true);
|
const autoSavePref = JSON.parse(localStorage.getItem(AUTOSAVE_KEY) ?? true);
|
||||||
setAutoSaveEnabled(autoSavePref);
|
setAutoSaveEnabled(autoSavePref);
|
||||||
@@ -126,29 +144,6 @@ const EditPage = (props)=>{
|
|||||||
editorRef.current?.update();
|
editorRef.current?.update();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBrewChange = (field)=>(value, subfield)=>{ //'text', 'style', 'snippets', 'metadata'
|
|
||||||
if(subfield == 'renderer' || subfield == 'theme')
|
|
||||||
fetchThemeBundle(setError, setThemeBundle, value.renderer, value.theme);
|
|
||||||
|
|
||||||
//If there are HTML errors, run the validator on every change to give quick feedback
|
|
||||||
if(HTMLErrors.length && (field == 'text' || field == 'snippets'))
|
|
||||||
setHTMLErrors(hbfm.validate(value));
|
|
||||||
|
|
||||||
if(field == 'metadata') setCurrentBrew((prev)=>({ ...prev, ...value }));
|
|
||||||
else setCurrentBrew((prev)=>({ ...prev, [field]: value }));
|
|
||||||
|
|
||||||
if(useLocalStorage) {
|
|
||||||
if(field == 'text') localStorage.setItem(BREWKEY, 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
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateBrew = (newData)=>setCurrentBrew((prevBrew)=>({
|
const updateBrew = (newData)=>setCurrentBrew((prevBrew)=>({
|
||||||
...prevBrew,
|
...prevBrew,
|
||||||
style : newData.style,
|
style : newData.style,
|
||||||
|
|||||||
@@ -10,18 +10,20 @@ import _ from 'lodash';
|
|||||||
import { DEFAULT_BREW } from '../../../../server/brewDefaults.js';
|
import { DEFAULT_BREW } from '../../../../server/brewDefaults.js';
|
||||||
import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js';
|
import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js';
|
||||||
|
|
||||||
|
import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.js'
|
||||||
|
|
||||||
import SplitPane from '@components/splitPane/splitPane.jsx';
|
import SplitPane from '@components/splitPane/splitPane.jsx';
|
||||||
import Editor from '../../editor/editor.jsx';
|
import Editor from '../../editor/editor.jsx';
|
||||||
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
||||||
|
|
||||||
import Nav from '@navbar/nav.jsx';
|
import Nav from '@navbar/nav.jsx';
|
||||||
import Navbar from '@navbar/navbar.jsx';
|
import Navbar from '@navbar/navbar.jsx';
|
||||||
import NewBrewItem from '@navbar/newbrew.navitem.jsx';
|
import NewBrewItem from '@navbar/newbrew.navitem.jsx';
|
||||||
import AccountNavItem from '@navbar/account.navitem.jsx';
|
import AccountNavItem from '@navbar/account.navitem.jsx';
|
||||||
import ErrorNavItem from '@navbar/error-navitem.jsx';
|
import ErrorNavItem from '@navbar/error-navitem.jsx';
|
||||||
import HelpNavItem from '@navbar/help.navitem.jsx';
|
import HelpNavItem from '@navbar/help.navitem.jsx';
|
||||||
import VaultNavItem from '@navbar/vault.navitem.jsx';
|
import VaultNavItem from '@navbar/vault.navitem.jsx';
|
||||||
import PrintNavItem from '@navbar/print.navitem.jsx';
|
import PrintNavItem from '@navbar/print.navitem.jsx';
|
||||||
import RecentNavItems from '@navbar/recent.navitem.jsx';
|
import RecentNavItems from '@navbar/recent.navitem.jsx';
|
||||||
const { both: RecentNavItem } = RecentNavItems;
|
const { both: RecentNavItem } = RecentNavItems;
|
||||||
|
|
||||||
@@ -60,6 +62,23 @@ const HomePage =(props)=>{
|
|||||||
const lastSavedBrew = useRef(_.cloneDeep(props.brew));
|
const lastSavedBrew = useRef(_.cloneDeep(props.brew));
|
||||||
const unsavedChangesRef = useRef(unsavedChanges);
|
const unsavedChangesRef = useRef(unsavedChanges);
|
||||||
|
|
||||||
|
const {
|
||||||
|
handleBrewChange
|
||||||
|
} = useCommonEditPageFunctions({
|
||||||
|
setError,
|
||||||
|
setThemeBundle,
|
||||||
|
HTMLErrors,
|
||||||
|
setHTMLErrors,
|
||||||
|
setCurrentBrew,
|
||||||
|
useLocalStorage,
|
||||||
|
BREWKEY,
|
||||||
|
STYLEKEY,
|
||||||
|
SNIPKEY,
|
||||||
|
METAKEY,
|
||||||
|
fetchThemeBundle,
|
||||||
|
hbfm
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
fetchThemeBundle(setError, setThemeBundle, currentBrew.renderer, currentBrew.theme);
|
fetchThemeBundle(setError, setThemeBundle, currentBrew.renderer, currentBrew.theme);
|
||||||
|
|
||||||
@@ -112,29 +131,6 @@ const HomePage =(props)=>{
|
|||||||
editorRef.current.update();
|
editorRef.current.update();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBrewChange = (field)=>(value, subfield)=>{ //'text', 'style', 'snippets', 'metadata'
|
|
||||||
if(subfield == 'renderer' || subfield == 'theme')
|
|
||||||
fetchThemeBundle(setError, setThemeBundle, value.renderer, value.theme);
|
|
||||||
|
|
||||||
//If there are HTML errors, run the validator on every change to give quick feedback
|
|
||||||
if(HTMLErrors.length && (field == 'text' || field == 'snippets'))
|
|
||||||
setHTMLErrors(hbfm.validate(value));
|
|
||||||
|
|
||||||
if(field == 'metadata') setCurrentBrew((prev)=>({ ...prev, ...value }));
|
|
||||||
else setCurrentBrew((prev)=>({ ...prev, [field]: value }));
|
|
||||||
|
|
||||||
if(useLocalStorage) {
|
|
||||||
if(field == 'text') localStorage.setItem(BREWKEY, 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
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderSaveButton = ()=>{
|
const renderSaveButton = ()=>{
|
||||||
// #1 - Currently saving, show SAVING
|
// #1 - Currently saving, show SAVING
|
||||||
if(isSaving)
|
if(isSaving)
|
||||||
|
|||||||
@@ -10,18 +10,20 @@ import _ from 'lodash';
|
|||||||
import { DEFAULT_BREW } from '../../../../server/brewDefaults.js';
|
import { DEFAULT_BREW } from '../../../../server/brewDefaults.js';
|
||||||
import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '@shared/helpers.js';
|
import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '@shared/helpers.js';
|
||||||
|
|
||||||
|
import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.js'
|
||||||
|
|
||||||
import SplitPane from '@components/splitPane/splitPane.jsx';
|
import SplitPane from '@components/splitPane/splitPane.jsx';
|
||||||
import Editor from '../../editor/editor.jsx';
|
import Editor from '../../editor/editor.jsx';
|
||||||
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
||||||
|
|
||||||
import Nav from '@navbar/nav.jsx';
|
import Nav from '@navbar/nav.jsx';
|
||||||
import Navbar from '@navbar/navbar.jsx';
|
import Navbar from '@navbar/navbar.jsx';
|
||||||
import NewBrewItem from '@navbar/newbrew.navitem.jsx';
|
import NewBrewItem from '@navbar/newbrew.navitem.jsx';
|
||||||
import AccountNavItem from '@navbar/account.navitem.jsx';
|
import AccountNavItem from '@navbar/account.navitem.jsx';
|
||||||
import ErrorNavItem from '@navbar/error-navitem.jsx';
|
import ErrorNavItem from '@navbar/error-navitem.jsx';
|
||||||
import HelpNavItem from '@navbar/help.navitem.jsx';
|
import HelpNavItem from '@navbar/help.navitem.jsx';
|
||||||
import VaultNavItem from '@navbar/vault.navitem.jsx';
|
import VaultNavItem from '@navbar/vault.navitem.jsx';
|
||||||
import PrintNavItem from '@navbar/print.navitem.jsx';
|
import PrintNavItem from '@navbar/print.navitem.jsx';
|
||||||
import RecentNavItems from '@navbar/recent.navitem.jsx';
|
import RecentNavItems from '@navbar/recent.navitem.jsx';
|
||||||
const { both: RecentNavItem } = RecentNavItems;
|
const { both: RecentNavItem } = RecentNavItems;
|
||||||
|
|
||||||
@@ -61,6 +63,23 @@ const NewPage = (props)=>{
|
|||||||
const trySaveRef = useRef(null); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew
|
const trySaveRef = useRef(null); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew
|
||||||
const unsavedChangesRef = useRef(unsavedChanges); // Similarly, onBeforeUnload lives outside React and needs ref to unsavedChanges
|
const unsavedChangesRef = useRef(unsavedChanges); // Similarly, onBeforeUnload lives outside React and needs ref to unsavedChanges
|
||||||
|
|
||||||
|
const {
|
||||||
|
handleBrewChange
|
||||||
|
} = useCommonEditPageFunctions({
|
||||||
|
setError,
|
||||||
|
setThemeBundle,
|
||||||
|
HTMLErrors,
|
||||||
|
setHTMLErrors,
|
||||||
|
setCurrentBrew,
|
||||||
|
useLocalStorage,
|
||||||
|
BREWKEY,
|
||||||
|
STYLEKEY,
|
||||||
|
SNIPKEY,
|
||||||
|
METAKEY,
|
||||||
|
fetchThemeBundle,
|
||||||
|
hbfm
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
loadBrew();
|
loadBrew();
|
||||||
fetchThemeBundle(setError, setThemeBundle, currentBrew.renderer, currentBrew.theme);
|
fetchThemeBundle(setError, setThemeBundle, currentBrew.renderer, currentBrew.theme);
|
||||||
@@ -127,29 +146,6 @@ const NewPage = (props)=>{
|
|||||||
editorRef.current.update();
|
editorRef.current.update();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBrewChange = (field)=>(value, subfield)=>{ //'text', 'style', 'snippets', 'metadata'
|
|
||||||
if(subfield == 'renderer' || subfield == 'theme')
|
|
||||||
fetchThemeBundle(setError, setThemeBundle, value.renderer, value.theme);
|
|
||||||
|
|
||||||
//If there are HTML errors, run the validator on every change to give quick feedback
|
|
||||||
if(HTMLErrors.length && (field == 'text' || field == 'snippets'))
|
|
||||||
setHTMLErrors(hbfm.validate(value));
|
|
||||||
|
|
||||||
if(field == 'metadata') setCurrentBrew((prev)=>({ ...prev, ...value }));
|
|
||||||
else setCurrentBrew((prev)=>({ ...prev, [field]: value }));
|
|
||||||
|
|
||||||
if(useLocalStorage) {
|
|
||||||
if(field == 'text') localStorage.setItem(BREWKEY, 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
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const trySave = async ()=>{
|
const trySave = async ()=>{
|
||||||
setIsSaving(true);
|
setIsSaving(true);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
export default function useCommonEditPageFunctions(dependencies) {
|
||||||
|
const {
|
||||||
|
setError,
|
||||||
|
setThemeBundle,
|
||||||
|
HTMLErrors,
|
||||||
|
setHTMLErrors,
|
||||||
|
setCurrentBrew,
|
||||||
|
useLocalStorage,
|
||||||
|
BREWKEY,
|
||||||
|
STYLEKEY,
|
||||||
|
SNIPKEY,
|
||||||
|
METAKEY,
|
||||||
|
fetchThemeBundle,
|
||||||
|
hbfm
|
||||||
|
} = dependencies;
|
||||||
|
|
||||||
|
const handleBrewChange = (field)=>(value, subfield)=>{ //'text', 'style', 'snippets', 'metadata'
|
||||||
|
if(subfield == 'renderer' || subfield == 'theme')
|
||||||
|
fetchThemeBundle(setError, setThemeBundle, value.renderer, value.theme);
|
||||||
|
|
||||||
|
//If there are HTML errors, run the validator on every change to give quick feedback
|
||||||
|
if(HTMLErrors.length && (field == 'text' || field == 'snippets'))
|
||||||
|
setHTMLErrors(hbfm.validate(value));
|
||||||
|
|
||||||
|
if(field == 'metadata') setCurrentBrew((prev)=>({ ...prev, ...value }));
|
||||||
|
else setCurrentBrew((prev)=>({ ...prev, [field]: value }));
|
||||||
|
|
||||||
|
if(useLocalStorage) {
|
||||||
|
if(field == 'text') localStorage.setItem(BREWKEY, 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
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
handleBrewChange
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
-15
@@ -12085,21 +12085,6 @@
|
|||||||
"url": "https://opencollective.com/mongoose"
|
"url": "https://opencollective.com/mongoose"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mongoose/node_modules/gcp-metadata": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-UcO3kefx6dCcZkgcTGgVOTFb7b1LlQ02hY1omMjjrrBzkajRMCFgYOjs7J71WqnuG1k2b+9ppGL7FsOfhZMQKQ==",
|
|
||||||
"extraneous": true,
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"gaxios": "^7.0.0",
|
|
||||||
"google-logging-utils": "^1.0.0",
|
|
||||||
"json-bigint": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mongoose/node_modules/mongodb": {
|
"node_modules/mongoose/node_modules/mongodb": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.5.0.tgz",
|
||||||
|
|||||||
Reference in New Issue
Block a user