@@ -48,6 +48,31 @@ interface State {
4848 pausedAt : number | undefined ;
4949}
5050
51+ const toastTimeouts = new Map < Toast [ 'id' ] , ReturnType < typeof setTimeout > > ( ) ;
52+
53+ const addToRemoveQueue = ( toastId : string ) => {
54+ if ( toastTimeouts . has ( toastId ) ) {
55+ return ;
56+ }
57+
58+ const timeout = setTimeout ( ( ) => {
59+ toastTimeouts . delete ( toastId ) ;
60+ dispatch ( {
61+ type : ActionType . REMOVE_TOAST ,
62+ toastId : toastId ,
63+ } ) ;
64+ } , 1000 ) ;
65+
66+ toastTimeouts . set ( toastId , timeout ) ;
67+ } ;
68+
69+ const clearFromRemoveQueue = ( toastId : string ) => {
70+ const timeout = toastTimeouts . get ( toastId ) ;
71+ if ( timeout ) {
72+ clearTimeout ( timeout ) ;
73+ }
74+ } ;
75+
5176export const reducer = ( state : State , action : Action ) : State => {
5277 switch ( action . type ) {
5378 case ActionType . ADD_TOAST :
@@ -57,6 +82,11 @@ export const reducer = (state: State, action: Action): State => {
5782 } ;
5883
5984 case ActionType . UPDATE_TOAST :
85+ // ! Side effects !
86+ if ( action . toast . id ) {
87+ clearFromRemoveQueue ( action . toast . id ) ;
88+ }
89+
6090 return {
6191 ...state ,
6292 toasts : state . toasts . map ( ( t ) =>
@@ -71,10 +101,21 @@ export const reducer = (state: State, action: Action): State => {
71101 : reducer ( state , { type : ActionType . ADD_TOAST , toast } ) ;
72102
73103 case ActionType . DISMISS_TOAST :
104+ const { toastId } = action ;
105+
106+ // ! Side effects ! - This could be execrated into a dismissToast() action, but I'll keep it here for simplicity
107+ if ( toastId ) {
108+ addToRemoveQueue ( toastId ) ;
109+ } else {
110+ state . toasts . forEach ( ( toast ) => {
111+ addToRemoveQueue ( toast . id ) ;
112+ } ) ;
113+ }
114+
74115 return {
75116 ...state ,
76117 toasts : state . toasts . map ( ( t ) =>
77- t . id === action . toastId || action . toastId === undefined
118+ t . id === toastId || toastId === undefined
78119 ? {
79120 ...t ,
80121 visible : false ,
0 commit comments