@@ -21,12 +21,24 @@ const levels = {
21
21
} ;
22
22
23
23
// See https://github.com/apvarun/toastify-js#api for options
24
- function showToast ( message , level , { gravity, position, duration, useHtmlBody, ...other } = { } ) {
24
+ function showToast ( message , level , { gravity, position, duration, useHtmlBody, preventDuplicates = true , ...other } = { } ) {
25
+ const body = useHtmlBody ? String ( message ) : htmlEscape ( message ) ;
26
+ const key = `${ level } -${ body } ` ;
27
+
28
+ // prevent showing duplicate toasts with same level and message, hide all existing toasts with same key
29
+ if ( preventDuplicates ) {
30
+ const toastElements = document . querySelectorAll ( `.toastify[data-toast-unique-key="${ CSS . escape ( key ) } "]` ) ;
31
+ for ( const el of toastElements ) {
32
+ el . remove ( ) ; // "hideToast" only removes the toast after an unchangeable delay, so we need to remove it immediately to make the "reposition" work with new toasts
33
+ el . _toastInst ?. hideToast ( ) ;
34
+ }
35
+ }
36
+
25
37
const { icon, background, duration : levelDuration } = levels [ level ?? 'info' ] ;
26
38
const toast = Toastify ( {
27
39
text : `
28
40
<div class='toast-icon'>${ svg ( icon ) } </div>
29
- <div class='toast-body'>${ useHtmlBody ? message : htmlEscape ( message ) } </div>
41
+ <div class='toast-body'>${ body } </div>
30
42
<button class='toast-close'>${ svg ( 'octicon-x' ) } </button>
31
43
` ,
32
44
escapeMarkup : false ,
@@ -39,6 +51,8 @@ function showToast(message, level, {gravity, position, duration, useHtmlBody, ..
39
51
40
52
toast . showToast ( ) ;
41
53
toast . toastElement . querySelector ( '.toast-close' ) . addEventListener ( 'click' , ( ) => toast . hideToast ( ) ) ;
54
+ toast . toastElement . setAttribute ( 'data-toast-unique-key' , key ) ;
55
+ toast . toastElement . _toastInst = toast ;
42
56
return toast ;
43
57
}
44
58
0 commit comments