Version 3 of the kit: - Radix UI replaced with Base UI (using the Shadcn UI patterns) - next-intl replaces react-i18next - enhanceAction deprecated; usage moved to next-safe-action - main layout now wrapped with [locale] path segment - Teams only mode - Layout updates - Zod v4 - Next.js 16.2 - Typescript 6 - All other dependencies updated - Removed deprecated Edge CSRF - Dynamic Github Action runner
47 lines
1.3 KiB
TypeScript
47 lines
1.3 KiB
TypeScript
interface AsyncDialogState {
|
|
getSessionId: () => number;
|
|
isCurrentSession: (sessionId: number) => boolean;
|
|
isPending: () => boolean;
|
|
setPending: (sessionId: number, pending: boolean) => void;
|
|
syncOpen: (open: boolean) => void;
|
|
}
|
|
|
|
export function createAsyncDialogState(initialOpen = false): AsyncDialogState {
|
|
let isOpen = initialOpen;
|
|
let sessionId = initialOpen ? 1 : 0;
|
|
const pendingCountBySession = new Map<number, number>();
|
|
|
|
const getPendingCount = () => pendingCountBySession.get(sessionId) ?? 0;
|
|
|
|
return {
|
|
getSessionId: () => sessionId,
|
|
isCurrentSession: (candidateSessionId) => candidateSessionId === sessionId,
|
|
isPending: () => getPendingCount() > 0,
|
|
setPending: (targetSessionId, pending) => {
|
|
if (targetSessionId !== sessionId) return;
|
|
|
|
const currentPendingCount =
|
|
pendingCountBySession.get(targetSessionId) ?? 0;
|
|
const nextPendingCount = pending
|
|
? currentPendingCount + 1
|
|
: Math.max(0, currentPendingCount - 1);
|
|
|
|
if (nextPendingCount === 0) {
|
|
pendingCountBySession.delete(targetSessionId);
|
|
return;
|
|
}
|
|
|
|
pendingCountBySession.set(targetSessionId, nextPendingCount);
|
|
},
|
|
syncOpen: (nextOpen) => {
|
|
if (nextOpen === isOpen) return;
|
|
|
|
isOpen = nextOpen;
|
|
|
|
if (nextOpen) {
|
|
sessionId += 1;
|
|
}
|
|
},
|
|
};
|
|
}
|