Files
plane/web/core/hooks/use-auto-save.tsx
M. Palanikannan 99184371f7 [WEB-1727] refactor: pages editor sync logic solidified (#4926)
* feat: pages editor sync logic solidified

* chore: added validation for archive and lock in a page

* feat: pages editor sync logic solidified

* fix: updated the auto save hook to run every 10s instead of 10s after the user stops typing!!

* chore: custom status code for pages

* fix: forceSync in case of auto save

* fix: modifying a locked and archived page shows a toast for now!

* fix: build errors and better error messages

* chore: page root moved

---------

Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-06-25 18:58:57 +05:30

74 lines
2.1 KiB
TypeScript

import { useEffect, useRef } from "react";
import { debounce } from "lodash";
const AUTO_SAVE_TIME = 10000;
const useAutoSave = (handleSaveDescription: (forceSync?: boolean, yjsAsUpdate?: Uint8Array) => void) => {
const intervalIdRef = useRef<NodeJS.Timeout | null>(null);
const handleSaveDescriptionRef = useRef(handleSaveDescription);
// Update the ref to always point to the latest handleSaveDescription
useEffect(() => {
handleSaveDescriptionRef.current = handleSaveDescription;
}, [handleSaveDescription]);
// Set up the interval to run every 10 seconds
useEffect(() => {
intervalIdRef.current = setInterval(() => {
try {
handleSaveDescriptionRef.current(true);
} catch (error) {
console.error("Autosave before manual save failed:", error);
}
}, AUTO_SAVE_TIME);
return () => {
if (intervalIdRef.current) {
clearInterval(intervalIdRef.current);
}
};
}, []);
// Debounced save function for manual save (Ctrl+S or Cmd+S) and clearing the
// interval for auto save and setting up the interval again
useEffect(() => {
const debouncedSave = debounce(() => {
try {
handleSaveDescriptionRef.current();
} catch (error) {
console.error("Manual save failed:", error);
}
if (intervalIdRef.current) {
clearInterval(intervalIdRef.current);
intervalIdRef.current = setInterval(() => {
try {
handleSaveDescriptionRef.current(true);
} catch (error) {
console.error("Autosave after manual save failed:", error);
}
}, AUTO_SAVE_TIME);
}
}, 500);
const handleSave = (e: KeyboardEvent) => {
const { ctrlKey, metaKey, key } = e;
const cmdClicked = ctrlKey || metaKey;
if (cmdClicked && key.toLowerCase() === "s") {
e.preventDefault();
e.stopPropagation();
debouncedSave();
}
};
window.addEventListener("keydown", handleSave);
return () => {
window.removeEventListener("keydown", handleSave);
};
}, []);
};
export default useAutoSave;