diff --git a/apps/web/src/components/ui/report/plugins/markdown-kit/platejs-conversion.test.ts b/apps/web/src/components/ui/report/plugins/markdown-kit/platejs-conversion.test.ts index 25155152d..e81fdfb1e 100644 --- a/apps/web/src/components/ui/report/plugins/markdown-kit/platejs-conversion.test.ts +++ b/apps/web/src/components/ui/report/plugins/markdown-kit/platejs-conversion.test.ts @@ -1737,7 +1737,6 @@ Another escaped: \\content\\`; for (let i = 0; i < 3; i++) { const platejs = await markdownToPlatejs(editor, result); result = await platejsToMarkdown(editor, platejs); - console.log(i, result); } // Metric should not be escaped @@ -1809,7 +1808,6 @@ Text with "quotes" and 'apostrophes'.`; const platejs = await markdownToPlatejs(editor, markdown); const serializedPlateJS = JSON.parse(JSON.stringify(platejs)); const backToMarkdown = await platejsToMarkdown(editor, serializedPlateJS); - console.log('backToMarkdown', backToMarkdown); expect(backToMarkdown).not.toContain('\\ | null; +}>({ blocker: false, + cooldownBlockerTimer: null, }); export const setBlocker = (blocker: boolean) => { - blockerStore.setState({ blocker }); + blockerStore.setState((v) => ({ ...v, blocker })); }; export const getBlocker = () => { @@ -14,7 +18,7 @@ export const getBlocker = () => { }; export const resetBlocker = () => { - blockerStore.setState({ blocker: false }); + blockerStore.setState((v) => ({ ...v, blocker: false })); }; export const useIsBlockerEnabled = () => { @@ -28,3 +32,38 @@ export const useIsBlockerEnabled = () => { resetBlocker, }; }; + +//blocker cooldown timer +export const startCooldownTimer = (timeout: number = 750) => { + const timeoutId = setTimeout(() => { + cancelCooldownTimer(); + }, timeout); + + blockerStore.setState((v) => ({ + ...v, + cooldownBlockerTimer: timeoutId, + })); +}; + +export const cancelCooldownTimer = () => { + if (blockerStore.state.cooldownBlockerTimer) { + clearTimeout(blockerStore.state.cooldownBlockerTimer); + blockerStore.setState((v) => ({ ...v, cooldownBlockerTimer: null })); + } +}; + +export const useCooldownTimer = () => { + const cooldownBlockerTimer = useStore( + blockerStore, + useCallback( + (v: { cooldownBlockerTimer: typeof blockerStore.state.cooldownBlockerTimer }) => + v.cooldownBlockerTimer, + [] + ) + ); + return { + cooldownBlockerTimer, + startCooldownTimer, + cancelCooldownTimer, + }; +}; diff --git a/apps/web/src/context/Routes/useBlockerWithModal.tsx b/apps/web/src/context/Routes/useBlockerWithModal.tsx index de62b1656..4b6309d2e 100644 --- a/apps/web/src/context/Routes/useBlockerWithModal.tsx +++ b/apps/web/src/context/Routes/useBlockerWithModal.tsx @@ -1,11 +1,11 @@ import { useBlocker } from '@tanstack/react-router'; -import { useEffect, useRef, useState } from 'react'; +import { useEffect } from 'react'; import type { ConfirmProps } from '@/components/ui/modal/ConfirmModal'; import { useMemoizedFn } from '@/hooks/useMemoizedFn'; import { useUnmount } from '@/hooks/useUnmount'; import { timeout } from '@/lib/timeout'; import { useOpenConfirmModal } from '../BusterNotifications'; -import { setBlocker } from './blocker-store'; +import { setBlocker, useCooldownTimer } from './blocker-store'; export const useBlockerWithModal = ({ onReset, @@ -24,24 +24,10 @@ export const useBlockerWithModal = ({ cancelButtonProps?: ConfirmProps['cancelButtonProps']; enableBeforeUnload?: boolean; }) => { - const [explicitlyUnblocked, setExplicitlyUnblocked] = useState(false); - const cooldownTimer = useRef | undefined>(undefined); + const { cooldownBlockerTimer, startCooldownTimer, cancelCooldownTimer } = useCooldownTimer(); const openConfirmModal = useOpenConfirmModal(); - const cancelCooldownTimer = () => { - if (cooldownTimer.current) { - clearTimeout(cooldownTimer.current); - cooldownTimer.current = undefined; - } - setExplicitlyUnblocked(false); - }; - - const startCooldownTimer = () => { - setExplicitlyUnblocked(true); - cooldownTimer.current = setTimeout(() => { - cancelCooldownTimer(); - }, 500); - }; + const isBlockerDisabled = !enableBlocker || !!cooldownBlockerTimer; const ensureBlockerIsUnBlocked = useMemoizedFn(async (iteration = 0) => { if (enableBlocker === false || iteration > 30) { @@ -52,6 +38,12 @@ export const useBlockerWithModal = ({ return ensureBlockerIsUnBlocked(iteration + 1); }); + //this must be a moized funciton because shouldBlockFn caches the function + const checkShouldBlockFn = useMemoizedFn(() => { + if (isBlockerDisabled) return true; + return false; + }); + useUnmount(() => { cancelCooldownTimer(); }); @@ -61,13 +53,13 @@ export const useBlockerWithModal = ({ }, [enableBlocker]); useBlocker({ - disabled: !enableBlocker || explicitlyUnblocked, + disabled: isBlockerDisabled, shouldBlockFn: async () => { - if (!enableBlocker) return false; + if (checkShouldBlockFn()) return false; const shouldLeave = await openConfirmModal({ title: title || 'Unsaved changes', - content: content, + content, primaryButtonProps: primaryButtonProps || { text: 'Yes, leave', }, @@ -79,6 +71,7 @@ export const useBlockerWithModal = ({ await onReset(); await ensureBlockerIsUnBlocked(); startCooldownTimer(); + await timeout(25); return Promise.resolve(true); }, onCancel: async () => {