Move resetWarnUnsavedTimer and ToggleAutosave to common hook

This commit is contained in:
Trevor Buckner
2026-09-13 13:20:45 -04:00
parent f89a7e8853
commit 18c29daf92
4 changed files with 34 additions and 44 deletions
+5 -19
View File
@@ -39,8 +39,6 @@ import { updateHistory, versionHistoryGarbageCollection } from '../../utils/vers
import googleDriveIcon from '../../googleDrive.svg'; import googleDriveIcon from '../../googleDrive.svg';
const SAVE_TIMEOUT = 10000; 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 BREWKEY = 'HB_newPage_content'; const BREWKEY = 'HB_newPage_content';
const STYLEKEY = 'HB_newPage_style'; const STYLEKEY = 'HB_newPage_style';
@@ -77,7 +75,6 @@ const EditPage = (props)=>{
const editorRef = useRef(null); const editorRef = useRef(null);
const lastSavedBrew = useRef(_.cloneDeep(props.brew)); const lastSavedBrew = useRef(_.cloneDeep(props.brew));
const saveTimeout = useRef(null); const saveTimeout = useRef(null);
const warnUnsavedTimeout = useRef(null);
const updateBrew = (newData)=>setCurrentBrew((prevBrew)=>({ const updateBrew = (newData)=>setCurrentBrew((prevBrew)=>({
...prevBrew, ...prevBrew,
@@ -86,12 +83,6 @@ const EditPage = (props)=>{
snippets : newData.snippets snippets : newData.snippets
})); }));
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 handleGoogleClick = ()=>{ const handleGoogleClick = ()=>{
if(currentBrew.authors.length > 0 && global.account?.username !== currentBrew.authors[0]) { if(currentBrew.authors.length > 0 && global.account?.username !== currentBrew.authors[0]) {
setAlertOwnershipToTransfer(true); setAlertOwnershipToTransfer(true);
@@ -272,14 +263,6 @@ const EditPage = (props)=>{
return <Nav.item className='save saved'>saved</Nav.item>; return <Nav.item className='save saved'>saved</Nav.item>;
}; };
const toggleAutoSave = ()=>{
clearTimeout(warnUnsavedTimeout.current);
clearTimeout(saveTimeout.current);
localStorage.setItem(AUTOSAVE_KEY, JSON.stringify(!autoSaveEnabled));
setAutoSaveEnabled(!autoSaveEnabled);
setWarnUnsavedChanges(autoSaveEnabled);
};
const renderAutoSaveButton = ()=>( const renderAutoSaveButton = ()=>(
<Nav.item onClick={toggleAutoSave}> <Nav.item onClick={toggleAutoSave}>
Autosave <i className={autoSaveEnabled ? 'fas fa-power-off active' : 'fas fa-power-off'}></i> Autosave <i className={autoSaveEnabled ? 'fas fa-power-off active' : 'fas fa-power-off'}></i>
@@ -317,8 +300,10 @@ const EditPage = (props)=>{
}; };
const { const {
resetWarnUnsavedTimer,
handleSplitMove, handleSplitMove,
handleBrewChange handleBrewChange,
toggleAutoSave
} = useCommonEditPageFunctions({ } = useCommonEditPageFunctions({
saveGoogle, saveGoogle,
setError, setError,
@@ -341,7 +326,8 @@ const EditPage = (props)=>{
trySave, trySave,
sandbox, sandbox,
lastSavedBrew, lastSavedBrew,
editorRef editorRef,
saveTimeout
}); });
return ( return (
+1 -9
View File
@@ -32,8 +32,6 @@ import Headtags from '@vitreum/headtags.js';
const Meta = Headtags.Meta; const Meta = Headtags.Meta;
const SAVE_TIMEOUT = 10000; 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 BREWKEY = 'HB_newPage_content'; const BREWKEY = 'HB_newPage_content';
const STYLEKEY = 'HB_newPage_style'; const STYLEKEY = 'HB_newPage_style';
@@ -64,7 +62,6 @@ const HomePage =(props)=>{
const editorRef = useRef(null); const editorRef = useRef(null);
const lastSavedBrew = useRef(_.cloneDeep(props.brew)); const lastSavedBrew = useRef(_.cloneDeep(props.brew));
const warnUnsavedTimeout = useRef(null);
const save = ()=>{ const save = ()=>{
request.post('/api') request.post('/api')
@@ -79,12 +76,6 @@ const HomePage =(props)=>{
}); });
}; };
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 = ()=>{ const renderSaveButton = ()=>{
// #1 - Currently saving, show SAVING // #1 - Currently saving, show SAVING
if(isSaving) if(isSaving)
@@ -142,6 +133,7 @@ const HomePage =(props)=>{
}; };
const { const {
resetWarnUnsavedTimer,
handleSplitMove, handleSplitMove,
handleBrewChange handleBrewChange
} = useCommonEditPageFunctions({ } = useCommonEditPageFunctions({
+1 -10
View File
@@ -29,8 +29,6 @@ const { both: RecentNavItem } = RecentNavItems;
// Page specific imports // Page specific imports
const SAVE_TIMEOUT = 10000; 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 BREWKEY = 'HB_newPage_content'; const BREWKEY = 'HB_newPage_content';
const STYLEKEY = 'HB_newPage_style'; const STYLEKEY = 'HB_newPage_style';
@@ -64,8 +62,6 @@ const NewPage = (props)=>{
const editorRef = useRef(null); const editorRef = useRef(null);
const lastSavedBrew = useRef(_.cloneDeep(props.brew)); const lastSavedBrew = useRef(_.cloneDeep(props.brew));
// const saveTimeout = useRef(null);
const warnUnsavedTimeout = useRef(null);
useEffect(()=>{ useEffect(()=>{
loadBrew(); loadBrew();
@@ -100,12 +96,6 @@ const NewPage = (props)=>{
window.history.replaceState({}, window.location.title, '/new/'); window.history.replaceState({}, window.location.title, '/new/');
}; };
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 = useEffectEvent(async ()=>{ const trySave = useEffectEvent(async ()=>{
setIsSaving(true); setIsSaving(true);
@@ -196,6 +186,7 @@ const NewPage = (props)=>{
); );
const { const {
resetWarnUnsavedTimer,
handleSplitMove, handleSplitMove,
handleBrewChange handleBrewChange
} = useCommonEditPageFunctions({ } = useCommonEditPageFunctions({
@@ -4,6 +4,9 @@ import _ from 'lodash';
const AUTOSAVE_KEY = 'HB_editor_autoSaveOn'; const AUTOSAVE_KEY = 'HB_editor_autoSaveOn';
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
export default function useCommonEditPageFunctions(dependencies) { export default function useCommonEditPageFunctions(dependencies) {
const { const {
setError, setError,
@@ -27,10 +30,12 @@ export default function useCommonEditPageFunctions(dependencies) {
unsavedChanges, unsavedChanges,
setUnsavedChanges, setUnsavedChanges,
lastSavedBrew, lastSavedBrew,
editorRef editorRef,
saveTimeout = undefined
} = dependencies; } = dependencies;
const unsavedChangesRef = useRef(unsavedChanges); // onBeforeUnload lives outside React and needs ref to unsavedChanges const unsavedChangesRef = useRef(unsavedChanges); // onBeforeUnload lives outside React and needs ref to unsavedChanges
const warnUnsavedTimeout = useRef(null); // timers live outside React and need ref to consistently track time
//==--------- Page setup ----------==// //==--------- Page setup ----------==//
useEffect(()=>{ useEffect(()=>{
@@ -70,6 +75,12 @@ export default function useCommonEditPageFunctions(dependencies) {
if(autoSaveEnabled) trySave(false, hasChange, saveGoogle); if(autoSaveEnabled) trySave(false, hasChange, saveGoogle);
}, [currentBrew]); }, [currentBrew]);
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 handleSplitMove = ()=>{ const handleSplitMove = ()=>{
editorRef.current.update(); editorRef.current.update();
}; };
@@ -97,8 +108,18 @@ export default function useCommonEditPageFunctions(dependencies) {
} }
}; };
const toggleAutoSave = ()=>{
clearTimeout(warnUnsavedTimeout.current);
clearTimeout(saveTimeout.current);
localStorage.setItem(AUTOSAVE_KEY, JSON.stringify(!autoSaveEnabled));
setAutoSaveEnabled(!autoSaveEnabled);
setWarnUnsavedChanges(autoSaveEnabled);
};
return { return {
resetWarnUnsavedTimer,
handleSplitMove, handleSplitMove,
handleBrewChange handleBrewChange,
toggleAutoSave
} }
} }