mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-18 20:57:40 +02:00
Replace toast notifications and reconciliation module for improved stability
Replace the existing toast notification system and the BL Reconciliation module with robust, independent implementations to resolve React errors and improve performance. Replit-Commit-Author: Agent Replit-Commit-Session-Id: b163d4c0-de5e-4f4e-a9c0-aed4c7049718 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/b163d4c0-de5e-4f4e-a9c0-aed4c7049718/l61v0JT
This commit is contained in:
1 parent
c0e1b26599
commit
69c3d6805a
6 files changed
+297
-3
No files matched your search
@@ -0,0 +1,110 @@
|
||||
import { useState, useCallback, useEffect } from "react";
|
||||
|
||||
export interface Toast {
|
||||
id: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
variant?: "default" | "destructive" | "success";
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
interface ToastState {
|
||||
toasts: Toast[];
|
||||
}
|
||||
|
||||
let listeners: Array<(state: ToastState) => void> = [];
|
||||
let state: ToastState = { toasts: [] };
|
||||
let count = 0;
|
||||
|
||||
function genId() {
|
||||
count = (count + 1) % Number.MAX_SAFE_INTEGER;
|
||||
return count.toString();
|
||||
}
|
||||
|
||||
function dispatch(action: { type: string; toast?: any; toastId?: string }) {
|
||||
switch (action.type) {
|
||||
case "ADD_TOAST":
|
||||
state.toasts = [action.toast, ...state.toasts].slice(0, 3); // Max 3 toasts
|
||||
break;
|
||||
case "DISMISS_TOAST":
|
||||
if (action.toastId) {
|
||||
state.toasts = state.toasts.filter(t => t.id !== action.toastId);
|
||||
} else {
|
||||
state.toasts = [];
|
||||
}
|
||||
break;
|
||||
case "REMOVE_TOAST":
|
||||
state.toasts = state.toasts.filter(t => t.id !== action.toastId);
|
||||
break;
|
||||
}
|
||||
|
||||
listeners.forEach(listener => listener(state));
|
||||
}
|
||||
|
||||
function toast({
|
||||
title,
|
||||
description,
|
||||
variant = "default",
|
||||
duration = 5000,
|
||||
...props
|
||||
}: Omit<Toast, "id"> & { duration?: number }) {
|
||||
const id = genId();
|
||||
|
||||
const newToast: Toast = {
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
variant,
|
||||
duration,
|
||||
...props,
|
||||
};
|
||||
|
||||
dispatch({
|
||||
type: "ADD_TOAST",
|
||||
toast: newToast,
|
||||
});
|
||||
|
||||
// Auto remove after duration
|
||||
if (duration > 0) {
|
||||
setTimeout(() => {
|
||||
dispatch({
|
||||
type: "REMOVE_TOAST",
|
||||
toastId: id,
|
||||
});
|
||||
}, duration);
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
dismiss: () => dispatch({ type: "DISMISS_TOAST", toastId: id }),
|
||||
update: (updates: Partial<Toast>) =>
|
||||
dispatch({ type: "ADD_TOAST", toast: { ...newToast, ...updates } }),
|
||||
};
|
||||
}
|
||||
|
||||
function dismiss(toastId?: string) {
|
||||
dispatch({
|
||||
type: "DISMISS_TOAST",
|
||||
toastId,
|
||||
});
|
||||
}
|
||||
|
||||
export function useToast() {
|
||||
const [toastState, setToastState] = useState<ToastState>(state);
|
||||
|
||||
useEffect(() => {
|
||||
listeners.push(setToastState);
|
||||
return () => {
|
||||
const index = listeners.indexOf(setToastState);
|
||||
if (index > -1) {
|
||||
listeners.splice(index, 1);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return {
|
||||
toast,
|
||||
dismiss,
|
||||
toasts: toastState.toasts,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user