diff --git a/client/homebrew/navbar/navbar.jsx b/client/homebrew/navbar/navbar.jsx index db9a836c9..40e5aef71 100644 --- a/client/homebrew/navbar/navbar.jsx +++ b/client/homebrew/navbar/navbar.jsx @@ -9,22 +9,10 @@ const Navbar = createReactClass({ displayName : 'Navbar', getInitialState : function() { return { - // showNonChromeWarning: false, // uncomment if needed ver : global.version || '0.0.0' }; }, - /* - renderChromeWarning : function(){ - if(!this.state.showNonChromeWarning) return; - return - Optimized for Chrome -
- If you are experiencing rendering issues, use Chrome instead -
-
- }, -*/ render : function(){ return diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 36df0f1bb..df5e8e592 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -10,18 +10,20 @@ import _ from 'lodash'; import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js'; import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; +import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.js' + import SplitPane from '@components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '@navbar/nav.jsx'; -import Navbar from '@navbar/navbar.jsx'; -import NewBrewItem from '@navbar/newbrew.navitem.jsx'; -import AccountNavItem from '@navbar/account.navitem.jsx'; -import ErrorNavItem from '@navbar/error-navitem.jsx'; -import HelpNavItem from '@navbar/help.navitem.jsx'; -import VaultNavItem from '@navbar/vault.navitem.jsx'; -import PrintNavItem from '@navbar/print.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; import RecentNavItems from '@navbar/recent.navitem.jsx'; 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_POPUP_TIMEOUT = 4000; //Show the warning for 4 seconds - const AUTOSAVE_KEY = 'HB_editor_autoSaveOn'; const BREWKEY = 'HB_newPage_content'; const STYLEKEY = 'HB_newPage_style'; @@ -49,7 +50,7 @@ const SNIPKEY = 'HB_newPage_snippets'; const METAKEY = 'HB_newPage_meta'; const useLocalStorage = false; -const neverSaved = false; +const sandbox = false; const EditPage = (props)=>{ props = { @@ -82,8 +83,26 @@ 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 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(()=>{ - const autoSavePref = JSON.parse(localStorage.getItem(AUTOSAVE_KEY) ?? true); + const autoSavePref = !sandbox && JSON.parse(localStorage.getItem(AUTOSAVE_KEY) ?? true); + setAutoSaveEnabled(autoSavePref); setWarnUnsavedChanges(!autoSavePref); setHTMLErrors(hbfm.validate(currentBrew.text)); @@ -104,6 +123,7 @@ const EditPage = (props)=>{ if(unsavedChangesRef.current) return 'You have unsaved changes!'; }; + return ()=>{ document.removeEventListener('keydown', handleControlKeys); window.onbeforeunload = null; @@ -126,29 +146,6 @@ const EditPage = (props)=>{ 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)=>({ ...prevBrew, style : newData.style, @@ -163,8 +160,8 @@ const EditPage = (props)=>{ }; const handleGoogleClick = ()=>{ - if(global.account !== currentBrew.authors[0]) { - setalertOwnershipToTransfer(true); + if(currentBrew.authors.length > 0 && global.account?.username !== currentBrew.authors[0]) { + setAlertOwnershipToTransfer(true); return; } if(!global.account?.googleId) { @@ -181,7 +178,7 @@ const EditPage = (props)=>{ setAlertTrashedGoogleBrew(false); setAlertNoGoogleToTransfer(false); setConfirmGoogleTransfer(false); - setalertOwnershipToTransfer(false); + setAlertOwnershipToTransfer(false); }; const toggleGoogleStorage = (e)=>{ @@ -267,12 +264,11 @@ const EditPage = (props)=>{ Google Drive icon - - {alertOwnershipToTransfer && (
- You must be the Owner to transfer between the Homebrewery and Google Drive! - The owner of this file is {currentBrew.authors[0]} + You must be the Owner to transfer between the Homebrewery and Google Drive! + The owner of this file is {currentBrew.authors[0]}. +

Okay
)} @@ -318,12 +314,12 @@ const EditPage = (props)=>{ resetWarnUnsavedTimer(); const elapsedTime = Math.round((new Date() - lastSavedTime) / 1000 / 60); const text = elapsedTime === 0 - ? 'Autosave is OFF.' - : `Autosave is OFF, and you haven't saved for ${elapsedTime} minutes.`; + ? `Autosave is OFF${sandbox ? ' for this sandbox page' : ''}.` + : `Autosave is OFF${sandbox ? ' for this sandbox page' : ''}, and you haven't saved for ${elapsedTime} minutes.`; return - Reminder... -
{text}
+ Reminder... +
{text}
; } @@ -335,9 +331,9 @@ const EditPage = (props)=>{ if(autoSaveEnabled) return auto-saved; - // #5 - No unsaved changes, and has never been saved, hide the button - if(neverSaved) - return save now; + // #5 - Sandbox with no unsaved changes, and has never been saved, hide the button + if(sandbox) + return save now; // DEFAULT - No unsaved changes, show SAVED return saved; diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index 4dc505ea9..2e4137049 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -10,18 +10,20 @@ import _ from 'lodash'; import { DEFAULT_BREW } from '../../../../server/brewDefaults.js'; import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; +import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.js' + import SplitPane from '@components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '@navbar/nav.jsx'; -import Navbar from '@navbar/navbar.jsx'; -import NewBrewItem from '@navbar/newbrew.navitem.jsx'; -import AccountNavItem from '@navbar/account.navitem.jsx'; -import ErrorNavItem from '@navbar/error-navitem.jsx'; -import HelpNavItem from '@navbar/help.navitem.jsx'; -import VaultNavItem from '@navbar/vault.navitem.jsx'; -import PrintNavItem from '@navbar/print.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; @@ -30,18 +32,22 @@ const { both: RecentNavItem } = RecentNavItems; import Headtags from '@vitreum/headtags.js'; const Meta = Headtags.Meta; -const BREWKEY = 'homebrewery-new'; -const STYLEKEY = 'homebrewery-new-style'; -const SNIPKEY = 'homebrewery-new-snippets'; -const METAKEY = 'homebrewery-new-meta'; +const SAVE_TIMEOUT = 10000; +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 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 useLocalStorage = false; -const neverSaved = true; +const sandbox = true; const HomePage =(props)=>{ props = { brew : DEFAULT_BREW, - ver : '0.0.0', ...props }; @@ -54,13 +60,38 @@ const HomePage =(props)=>{ const [themeBundle, setThemeBundle] = useState({}); const [unsavedChanges, setUnsavedChanges] = useState(false); const [isSaving, setIsSaving] = useState(false); - const [autoSaveEnabled, setAutoSaveEnable] = useState(false); + const [lastSavedTime, setLastSavedTime] = useState(new Date()); + const [autoSaveEnabled, setAutoSaveEnabled] = useState(false); + const [warnUnsavedChanges, setWarnUnsavedChanges] = useState(true); const editorRef = useRef(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); + const warnUnsavedTimeout = useRef(null); const unsavedChangesRef = useRef(unsavedChanges); + const { + handleBrewChange + } = useCommonEditPageFunctions({ + setError, + setThemeBundle, + HTMLErrors, + setHTMLErrors, + setCurrentBrew, + useLocalStorage, + BREWKEY, + STYLEKEY, + SNIPKEY, + METAKEY, + fetchThemeBundle, + hbfm + }); + useEffect(()=>{ + const autoSavePref = !sandbox && JSON.parse(localStorage.getItem(AUTOSAVE_KEY) ?? true); + + setAutoSaveEnabled(autoSavePref); + setWarnUnsavedChanges(!autoSavePref); + setHTMLErrors(hbfm.validate(currentBrew.text)); fetchThemeBundle(setError, setThemeBundle, currentBrew.renderer, currentBrew.theme); const handleControlKeys = (e)=>{ @@ -78,6 +109,7 @@ const HomePage =(props)=>{ if(unsavedChangesRef.current) return 'You have unsaved changes!'; }; + return ()=>{ document.removeEventListener('keydown', handleControlKeys); window.onbeforeunload = null; @@ -112,27 +144,10 @@ const HomePage =(props)=>{ 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 resetWarnUnsavedTimer = ()=>{ + setTimeout(()=>setWarnUnsavedChanges(false), UNSAVED_WARNING_POPUP_TIMEOUT); // Hide the warning after 4 seconds + clearTimeout(warnUnsavedTimeout.current); + warnUnsavedTimeout.current = setTimeout(()=>setWarnUnsavedChanges(true), UNSAVED_WARNING_TIMEOUT); // 15 minutes between unsaved work warnings }; const renderSaveButton = ()=>{ @@ -141,18 +156,18 @@ const HomePage =(props)=>{ return saving...; // #2 - Unsaved changes exist, autosave is OFF and warning timer has expired, show AUTOSAVE WARNING - // if(unsavedChanges && warnUnsavedChanges) { - // resetWarnUnsavedTimer(); - // const elapsedTime = Math.round((new Date() - lastSavedTime) / 1000 / 60); - // const text = elapsedTime === 0 - // ? 'Autosave is OFF.' - // : `Autosave is OFF, and you haven't saved for ${elapsedTime} minutes.`; + if(unsavedChanges && warnUnsavedChanges) { + resetWarnUnsavedTimer(); + const elapsedTime = Math.round((new Date() - lastSavedTime) / 1000 / 60); + const text = elapsedTime === 0 + ? `Autosave is OFF${sandbox ? ' for this sandbox page' : ''}.` + : `Autosave is OFF${sandbox ? ' for this sandbox page' : ''}, and you haven't saved for ${elapsedTime} minutes.`; - // return - // Reminder... - //
{text}
- //
; - // } + return + Reminder... +
{text}
+
; + } // #3 - Unsaved changes exist, click to save, show SAVE NOW if(unsavedChanges) @@ -162,8 +177,8 @@ const HomePage =(props)=>{ if(autoSaveEnabled) return auto-saved; - // #5 - No unsaved changes, and has never been saved, hide the button - if(neverSaved) + // #5 - Sandbox with no unsaved changes, and has never been saved, hide the button + if(sandbox) return save now; // DEFAULT - No unsaved changes, show SAVED diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index c45090fb7..ff686e0a1 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -10,31 +10,38 @@ import _ from 'lodash'; import { DEFAULT_BREW } from '../../../../server/brewDefaults.js'; import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '@shared/helpers.js'; +import useCommonEditPageFunctions from '../../utils/commonEditPageFunctions.js' + import SplitPane from '@components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '@navbar/nav.jsx'; -import Navbar from '@navbar/navbar.jsx'; -import NewBrewItem from '@navbar/newbrew.navitem.jsx'; -import AccountNavItem from '@navbar/account.navitem.jsx'; -import ErrorNavItem from '@navbar/error-navitem.jsx'; -import HelpNavItem from '@navbar/help.navitem.jsx'; -import VaultNavItem from '@navbar/vault.navitem.jsx'; -import PrintNavItem from '@navbar/print.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; // Page specific imports +const SAVE_TIMEOUT = 10000; +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 AUTOSAVE_KEY = 'HB_editor_autoSaveOn'; const BREWKEY = 'HB_newPage_content'; const STYLEKEY = 'HB_newPage_style'; -const METAKEY = 'HB_newPage_metadata'; const SNIPKEY = 'HB_newPage_snippets'; +const METAKEY = 'HB_newPage_meta'; + const SAVEKEYPREFIX = 'HB_editor_defaultSave_'; const useLocalStorage = true; -const neverSaved = true; +const sandbox = true; const NewPage = (props)=>{ props = { @@ -44,6 +51,7 @@ const NewPage = (props)=>{ const [currentBrew, setCurrentBrew] = useState(props.brew); const [isSaving, setIsSaving] = useState(false); + const [lastSavedTime, setLastSavedTime] = useState(new Date()); const [saveGoogle, setSaveGoogle] = useState(global.account?.googleId ? true : false); const [error, setError] = useState(null); const [HTMLErrors, setHTMLErrors] = useState(hbfm.validate(props.brew.text)); @@ -53,16 +61,42 @@ const NewPage = (props)=>{ const [themeBundle, setThemeBundle] = useState({}); const [unsavedChanges, setUnsavedChanges] = useState(false); const [autoSaveEnabled, setAutoSaveEnabled] = useState(false); + const [warnUnsavedChanges, setWarnUnsavedChanges] = useState(true); const editorRef = useRef(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); // const saveTimeout = useRef(null); - // const warnUnsavedTimeout = useRef(null); + const warnUnsavedTimeout = useRef(null); 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 useEffect(()=>{ loadBrew(); + }, []); + + const { + handleBrewChange + } = useCommonEditPageFunctions({ + setError, + setThemeBundle, + HTMLErrors, + setHTMLErrors, + setCurrentBrew, + useLocalStorage, + BREWKEY, + STYLEKEY, + SNIPKEY, + METAKEY, + fetchThemeBundle, + hbfm + }); + + useEffect(()=>{ + const autoSavePref = !sandbox && JSON.parse(localStorage.getItem(AUTOSAVE_KEY) ?? true); + + setAutoSaveEnabled(autoSavePref); + setWarnUnsavedChanges(!autoSavePref); + setHTMLErrors(hbfm.validate(currentBrew.text)); fetchThemeBundle(setError, setThemeBundle, currentBrew.renderer, currentBrew.theme); const handleControlKeys = (e)=>{ @@ -76,9 +110,14 @@ const NewPage = (props)=>{ }; document.addEventListener('keydown', handleControlKeys); + window.onbeforeunload = ()=>{ + if(unsavedChangesRef.current) + return 'You have unsaved changes!'; + }; return ()=>{ document.removeEventListener('keydown', handleControlKeys); + window.onbeforeunload = null; }; }, []); @@ -127,27 +166,10 @@ const NewPage = (props)=>{ 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 resetWarnUnsavedTimer = ()=>{ + setTimeout(()=>setWarnUnsavedChanges(false), UNSAVED_WARNING_POPUP_TIMEOUT); // Hide the warning after 4 seconds + clearTimeout(warnUnsavedTimeout.current); + warnUnsavedTimeout.current = setTimeout(()=>setWarnUnsavedChanges(true), UNSAVED_WARNING_TIMEOUT); // 15 minutes between unsaved work warnings }; const trySave = async ()=>{ @@ -175,6 +197,7 @@ const NewPage = (props)=>{ localStorage.removeItem(BREWKEY); localStorage.removeItem(STYLEKEY); localStorage.removeItem(METAKEY); + window.onbeforeunload = null; window.location = `/edit/${savedBrew.editId}`; }; @@ -184,18 +207,18 @@ const NewPage = (props)=>{ return saving...; // #2 - Unsaved changes exist, autosave is OFF and warning timer has expired, show AUTOSAVE WARNING - // if(unsavedChanges && warnUnsavedChanges) { - // resetWarnUnsavedTimer(); - // const elapsedTime = Math.round((new Date() - lastSavedTime) / 1000 / 60); - // const text = elapsedTime === 0 - // ? 'Autosave is OFF.' - // : `Autosave is OFF, and you haven't saved for ${elapsedTime} minutes.`; + if(unsavedChanges && warnUnsavedChanges) { + resetWarnUnsavedTimer(); + const elapsedTime = Math.round((new Date() - lastSavedTime) / 1000 / 60); + const text = elapsedTime === 0 + ? `Autosave is OFF${sandbox ? ' for this sandbox page' : ''}.` + : `Autosave is OFF${sandbox ? ' for this sandbox page' : ''}, and you haven't saved for ${elapsedTime} minutes.`; - // return - // Reminder... - //
{text}
- //
; - // } + return + Reminder... +
{text}
+
; + } // #3 - Unsaved changes exist, click to save, show SAVE NOW if(unsavedChanges) @@ -205,8 +228,8 @@ const NewPage = (props)=>{ if(autoSaveEnabled) return auto-saved; - // #5 - No unsaved changes, and has never been saved, hide the button - if(neverSaved) + // #5 - Sandbox with no unsaved changes, and has never been saved, hide the button + if(sandbox) return save now; // DEFAULT - No unsaved changes, show SAVED diff --git a/client/homebrew/utils/commonEditPageFunctions.js b/client/homebrew/utils/commonEditPageFunctions.js new file mode 100644 index 000000000..bf397e334 --- /dev/null +++ b/client/homebrew/utils/commonEditPageFunctions.js @@ -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 + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8309fba77..f7d138beb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12085,21 +12085,6 @@ "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": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-7.5.0.tgz", diff --git a/shared/helpers.js b/shared/helpers.js index 667d7b6b1..db046b810 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -146,7 +146,7 @@ const printCurrentBrew = async ()=>{ } }; -const fetchThemeBundle = async (setError, setThemeBundle, renderer, theme)=>{ +const fetchThemeBundle = async (setError = ()=>{}, setThemeBundle = ()=>{}, renderer, theme)=>{ if(!renderer || !theme) return; const res = await request .get(`/api/theme/${renderer}/${theme}`)