I am currently facing a challenge where the progress bar line in my message queue does not reach the end of the message before it closes. I have included a brief video showcasing the issue along with the relevant code snippet. Any suggestions or ideas would be greatly appreciated!
Video: 1º: GenericSnackbarMessage
interface GenericSnackbarMessageProps {
id: string;
open: boolean;
onClose: () => void;
title?: string;
message?: string;
icon: ReactNode;
showLinearProgress?: boolean;
closeMessageAfterTime?: boolean;
isLastElement?: boolean;
activeTimer?: boolean;
}
const useProgressBarStyles = makeStyles(() =>
createStyles({
progressBar: {
// Custom styling for progress bar animation
'&[aria-valuenow="0"]': {
'& > $progressBarInner': {
transition: 'none',
},
},
},
progressBarInner: {},
})
);
const SlideTransition = (props: SlideProps) => <Slide {...props} direction="left" />;
const GenericSnackbarMessage = ({
id,
open,
onClose,
title = 'Title',
message = 'Insert message here',
icon,
showLinearProgress,
closeMessageAfterTime = true,
isLastElement,
activeTimer = true,
}: GenericSnackbarMessageProps) => {
const { palette } = useTheme();
const isDark = palette.mode === 'dark';
const handleClose = useCallback((): void => {
onClose();
}, [onClose]);
const classes = useProgressBarStyles();
const [progress, setProgress] = useState<number>(0);
// Additional functionality to handle the progress bar animation and timer
useEffect(() => {
if (!closeMessageAfterTime || !activeTimer || !isLastElement) return;
const startTime = Date.now();
const duration = 4000;
const updateProgress = (): void => {
const currentTime = Date.now();
const elapsedTime = currentTime - startTime;
const innerProgress = elapsedTime / duration * 100;
setProgress(innerProgress >= 100 ? 100 : innerProgress);
if (innerProgress >= 100 && elapsedTime >= duration) {
console.log('Progress at timer end:', innerProgress);
handleClose();
}
};
const timerId = setInterval(updateProgress, 100);
return (): void => {
clearInterval(timerId);
};
}, [closeMessageAfterTime, activeTimer, isLastElement, handleClose]);
return (
<Snackbar
open={open}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
TransitionComponent={SlideTransition}
>
<div>
<Alert
sx={{
// Styling configurations for the alert message display
}}
icon={!!icon && (
<Stack
justifyContent="center"
alignItems="center"
style={{
// Customize the appearance of the icon container
}}
>
{icon}
</Stack>
)}
action={(
<CrossIcon
style={{
// Styling for the closing icon
}}
onClick={handleClose}
/>
)}
>
<AlertTitle sx={{ paddingTop: 8 }}>
<Typography variant='headings.h4' color={isDark ? '#FFFFFF' : '#222221B2'}>{title}</Typography>
</AlertTitle>
<Typography variant='captions.default' color={isDark ? '#FFFFFF' : '#222221B2'}>{message}</Typography>
</Alert>
{showLinearProgress
&& (
<LinearProgress
variant="determinate"
className={classes.progressBar}
value={progress}
classes={{ bar: classes.progressBarInner }}
/>
)}
</div>
</Snackbar>
);
};
export default GenericSnackbarMessage;
export type { GenericSnackbarMessageProps };
interface SnackbarProviderProps{
children: React.ReactNode;
}
2º Provider
export const SnackbarProvider = ({ children }: SnackbarProviderProps): ReactElement => {
// State management for the snackbar queue
const [snackbarQueue, setSnackbarQueue] = useState<Array<GenericSnackbarMessageProps>>([]);
// Add a new snackbar message to the queue
const addSnackbar = useCallback(
(snackbarConfig: GenericSnackbarMessageProps): void => {
setSnackbarQueue((prev) => [...prev, snackbarConfig]);
},
[]
);
// Remove a specific snackbar from the queue
const removeSnackbar = (id: string): void => {
setSnackbarQueue((prev) => prev.filter((snackbar) => snackbar.id !== id));
};
// Context value for managing snackbar messages
const contextValue: SnackbarContextType = useMemo(() => ({
showGenericMessage: (snackbarConfig: GenericSnackbarMessageProps): void => {
addSnackbar(snackbarConfig);
},
clearAllSnackbars: (): void => {
setSnackbarQueue([]);
},
}), [addSnackbar]);
return (
<SnackbarContext.Provider value={contextValue}>
{children}
{snackbarQueue.length > 0
&& snackbarQueue.map((snackbar, index) => (
<GenericSnackbarMessage
key={snackbar.id}
{...snackbar}
title={`I'm number ${index}`}
isLastElement={snackbarQueue.length - 1 === index}
onClose={(): void => void removeSnackbar(snackbar.id)}
/>
))}
</SnackbarContext.Provider>
);
};