mirror of https://github.com/buster-so/buster.git
pass blocker as memoized function
This commit is contained in:
parent
0d393792f1
commit
3fd2c77357
|
@ -1737,7 +1737,6 @@ Another escaped: \\<div\\>content\\</div\\>`;
|
|||
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('\\<metric');
|
||||
expect(backToMarkdown).toContain('<metric metricId="json-test-metric"');
|
||||
|
||||
|
@ -1818,8 +1816,6 @@ Text with "quotes" and 'apostrophes'.`;
|
|||
const serializedPlateJS2 = JSON.parse(JSON.stringify(platejs2));
|
||||
const finalMarkdown = await platejsToMarkdown(editor, serializedPlateJS2);
|
||||
|
||||
console.log('finalMarkdown', finalMarkdown);
|
||||
|
||||
// Metric tags should never be escaped during JSON round trips
|
||||
expect(finalMarkdown).not.toContain('\\<metric');
|
||||
expect(finalMarkdown).toContain('<metric metricId="json-test-metric"');
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
import { Store, useStore } from '@tanstack/react-store';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const blockerStore = new Store({
|
||||
export const blockerStore = new Store<{
|
||||
blocker: boolean;
|
||||
cooldownBlockerTimer: ReturnType<typeof setTimeout> | 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,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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<ReturnType<typeof setTimeout> | 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<true>({
|
||||
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 () => {
|
||||
|
|
Loading…
Reference in New Issue