diff --git a/public/language/en-GB/global.json b/public/language/en-GB/global.json index 857bd05377..635b52a6e7 100644 --- a/public/language/en-GB/global.json +++ b/public/language/en-GB/global.json @@ -61,6 +61,8 @@ "alert.success": "Success", "alert.error": "Error", + "alert.warning": "Warning", + "alert.info": "Info", "alert.banned": "Banned", "alert.banned.message": "You have just been banned, your access is now restricted.", diff --git a/public/scss/admin/admin.scss b/public/scss/admin/admin.scss index 5003d75f94..d74d386cf4 100644 --- a/public/scss/admin/admin.scss +++ b/public/scss/admin/admin.scss @@ -17,7 +17,7 @@ @import "./extend/widgets"; @import "settings"; -@import "./modules/alerts"; +@import "../modules/alerts"; @import "./modules/selectable"; @import "./modules/nprogress"; @import "./modules/search"; diff --git a/public/scss/admin/modules/alerts.scss b/public/scss/admin/modules/alerts.scss deleted file mode 100644 index 54438c27bf..0000000000 --- a/public/scss/admin/modules/alerts.scss +++ /dev/null @@ -1,71 +0,0 @@ -.alert-window { - position: fixed; - width: 300px; - z-index: 10002; - - right: 20px; - bottom: 0px; - - .alert { - &::before { - position: relative; - top: -15px; - left: -15px; - display: block; - height: 2px; - width: 0; - transition: inherit; - } - - &.alert-info { - color: $info; - } - - &.alert-warning { - color: $warning; - } - - &.alert-success { - color: $success; - } - - &.alert-danger { - color: $danger; - } - - &.animate { - &.alert-info::before { - background-color: lighten($info, 25%); - } - - &.alert-warning::before { - background-color: lighten($warning, 25%); - } - - &.alert-success::before { - background-color: lighten($success, 25%); - } - - &.alert-danger::before { - background-color: lighten($danger, 25%); - } - - &::before { - width: calc(100% + 50px); - } - } - - background-color: var(--bs-body-bg); - border: 0; - border-left: 5px solid !important; - box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.25), 0px 2px 10px 0px rgba(0, 0, 0, 0.25); - - strong { - text-transform: uppercase; - } - - p { - padding: 10px 0px 0px; - } - } -} diff --git a/public/scss/client.scss b/public/scss/client.scss index 11e2d14c2f..3d134ceb42 100644 --- a/public/scss/client.scss +++ b/public/scss/client.scss @@ -4,4 +4,5 @@ @import "modals"; @import "modules/picture-switcher"; @import "modules/bottom-sheet"; -@import "modules/icon-picker"; \ No newline at end of file +@import "modules/icon-picker"; +@import "modules/alerts.scss"; \ No newline at end of file diff --git a/public/scss/modules/alerts.scss b/public/scss/modules/alerts.scss new file mode 100644 index 0000000000..25cf052df8 --- /dev/null +++ b/public/scss/modules/alerts.scss @@ -0,0 +1,45 @@ +.alert-window { + position: fixed; + width: 300px; + z-index: 10002; + + right: 20px; + bottom: 0px; + + .alert { + overflow: hidden; + position: relative; + + .alert-progress { + width: 0; + &.animate { + width: calc(100% + 50px); + } + } + + &.alert-info { + color: $info; + .alert-progress { background-color: $info; } + } + + &.alert-warning { + color: $warning; + .alert-progress { background-color: $warning; } + } + + &.alert-success { + color: $success; + .alert-progress { background-color: $success; } + } + + &.alert-danger { + color: $danger; + .alert-progress { background-color: $danger; } + } + + background-color: var(--bs-body-bg); + border: 0; + border-left: 5px solid !important; + box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.25), 0px 2px 10px 0px rgba(0, 0, 0, 0.25); + } +} diff --git a/public/src/modules/alerts.js b/public/src/modules/alerts.js index 4dc9d1aba5..3cc82137ca 100644 --- a/public/src/modules/alerts.js +++ b/public/src/modules/alerts.js @@ -27,6 +27,26 @@ export function success(message, timeout) { }); } +export function info(message, timeout) { + alert({ + alert_id: utils.generateUUID(), + title: '[[global:alert.info]]', + message: message, + type: 'info', + timeout: timeout || 5000, + }); +} + +export function warning(message, timeout) { + alert({ + alert_id: utils.generateUUID(), + title: '[[global:alert.warning]]', + message: message, + type: 'warning', + timeout: timeout || 5000, + }); +} + export function error(message, timeout) { message = (message && message.message) || message; @@ -52,7 +72,8 @@ export function remove(id) { function updateAlert(alert, params) { alert.find('strong').translateHtml(params.title); alert.find('p').translateHtml(params.message); - alert.attr('class', 'alert alert-dismissable alert-' + params.type + ' clearfix'); + alert.removeClass('alert-success alert-danger alert-info alert-warning') + .addClass(`alert-${params.type}`); clearTimeout(parseInt(alert.attr('timeoutId'), 10)); if (params.timeout) { @@ -67,10 +88,10 @@ function updateAlert(alert, params) { alert .addClass('pointer') .on('click', function (e) { - if (!$(e.target).is('.close')) { + if (!$(e.target).is('.btn-close')) { params.clickfn(); } - fadeOut(alert); + close(alert); }); } } @@ -82,17 +103,20 @@ function createNew(params) { return updateAlert(alert, params); } alert = html; - alert.fadeIn(200); - components.get('toaster/tray').prepend(alert); + alert.hide().fadeIn(200).prependTo(components.get('toaster/tray')); - if (typeof params.closefn === 'function') { - alert.find('button').on('click', function () { + alert.on('close.bs.alert', function () { + if (typeof params.closefn === 'function') { params.closefn(); - fadeOut(alert); - return false; - }); - } + } + const timeoutId = alert.attr('timeoutId'); + + if (timeoutId) { + clearTimeout(timeoutId); + alert.removeAttr('timeoutId'); + } + }); if (params.timeout) { startTimeout(alert, params); @@ -102,10 +126,10 @@ function createNew(params) { alert .addClass('pointer') .on('click', function (e) { - if (!$(e.target).is('.close')) { + if (!$(e.target).is('.btn-close')) { params.clickfn(alert, params); } - fadeOut(alert); + close(alert); }); } @@ -113,17 +137,16 @@ function createNew(params) { }); } -function fadeOut(alert) { - alert.fadeOut(500, function () { - $(this).remove(); - }); +function close(alert) { + alert.alert('close'); } function startTimeout(alert, params) { const timeout = params.timeout; const timeoutId = setTimeout(function () { - fadeOut(alert); + alert.removeAttr('timeoutId'); + close(alert); if (typeof params.timeoutfn === 'function') { params.timeoutfn(alert, params); @@ -133,20 +156,21 @@ function startTimeout(alert, params) { alert.attr('timeoutId', timeoutId); // Reset and start animation - alert.css('transition-property', 'none'); - alert.removeClass('animate'); + const alertProgress = alert.find('.alert-progress'); + alertProgress.css('transition-property', 'none'); + alertProgress.removeClass('animate'); setTimeout(function () { - alert.css('transition-property', ''); - alert.css('transition', 'width ' + (timeout + 450) + 'ms linear, background-color ' + (timeout + 450) + 'ms ease-in'); - alert.addClass('animate'); - hooks.fire('action:alert.animate', { alert, params }); + alertProgress.css('transition-property', ''); + alertProgress.css('transition', 'width ' + (timeout + 450) + 'ms linear'); + alertProgress.addClass('animate'); + hooks.fire('action:alert.animate', { alert, alertProgress, params }); }, 50); // Handle mouseenter/mouseleave alert .on('mouseenter', function () { - $(this).css('transition-duration', 0); + alertProgress.css('transition-duration', 0); }); }