Add toastify js as a OC.Notification replacement
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
parent
07ffe4a34a
commit
2d0337332d
7 changed files with 235 additions and 119 deletions
|
@ -8,4 +8,5 @@
|
|||
@import 'fixes.scss';
|
||||
@import 'mobile.scss';
|
||||
@import 'tooltip.scss';
|
||||
@import 'public.scss';
|
||||
@import 'toast.scss';
|
||||
@import 'public.scss';
|
||||
|
|
46
core/css/toast.scss
Normal file
46
core/css/toast.scss
Normal file
|
@ -0,0 +1,46 @@
|
|||
.toastify.toast {
|
||||
min-width: 200px;
|
||||
background: none;
|
||||
background-color: var(--color-main-background);
|
||||
color: var(--color-main-text);
|
||||
box-shadow: 0 0 6px 0 var(--color-box-shadow);
|
||||
padding: 12px;
|
||||
padding-right: 34px;
|
||||
margin-top: 45px;
|
||||
|
||||
.toast-close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 38px;
|
||||
opacity: 0.4;
|
||||
padding: 12px;
|
||||
@include icon-color('close', 'actions', $color-black, 2, true);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
text-indent: 200%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover, &:focus, &:active {
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.toastify.toastify-top {
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.toast-error {
|
||||
border-left: 3px solid var(--color-error);
|
||||
}
|
||||
.toast-info {
|
||||
border-left: 3px solid var(--color-primary);
|
||||
}
|
||||
.toast-warning {
|
||||
border-left: 3px solid var(--color-warning);
|
||||
}
|
||||
.toast-success {
|
||||
border-left: 3px solid var(--color-success);
|
||||
}
|
|
@ -21,24 +21,22 @@
|
|||
|
||||
import _ from 'underscore'
|
||||
import $ from 'jquery'
|
||||
import Toastify from 'toastify-js'
|
||||
|
||||
/**
|
||||
* @todo Write documentation
|
||||
* @deprecated 17.0.0 use OCP.Toast
|
||||
* @namespace OC.Notification
|
||||
*/
|
||||
export default {
|
||||
queuedNotifications: [],
|
||||
|
||||
updatableNotification: null,
|
||||
|
||||
getDefaultNotificationFunction: null,
|
||||
|
||||
/**
|
||||
* @type Array<int>
|
||||
* @description array of notification timers
|
||||
*/
|
||||
notificationTimers: [],
|
||||
|
||||
/**
|
||||
* @param callback
|
||||
* @todo Write documentation
|
||||
* @deprecated 17.0.0 use OCP.Toast
|
||||
*/
|
||||
setDefault: function (callback) {
|
||||
this.getDefaultNotificationFunction = callback;
|
||||
|
@ -52,10 +50,11 @@ export default {
|
|||
*
|
||||
* @param {jQuery} [$row] notification row
|
||||
* @param {Function} [callback] callback
|
||||
* @deprecated 17.0.0 use OCP.Toast
|
||||
*/
|
||||
hide: function ($row, callback) {
|
||||
var self = this;
|
||||
var $notification = $('#notification');
|
||||
var $notification = $('#content');
|
||||
|
||||
if (_.isFunction($row)) {
|
||||
// first arg is the callback
|
||||
|
@ -64,46 +63,23 @@ export default {
|
|||
}
|
||||
|
||||
if (!$row) {
|
||||
console.warn('Missing argument $row in OC.Notification.hide() call, caller needs to be adjusted to only dismiss its own notification');
|
||||
// assume that the row to be hidden is the first one
|
||||
$row = $notification.find('.row:first');
|
||||
}
|
||||
|
||||
if ($row && $notification.find('.row').length > 1) {
|
||||
// remove the row directly
|
||||
$row.remove();
|
||||
if (callback) {
|
||||
callback.call();
|
||||
}
|
||||
console.error('Missing argument $row in OC.Notification.hide() call, caller needs to be adjusted to only dismiss its own notification');
|
||||
return;
|
||||
}
|
||||
|
||||
_.defer(function () {
|
||||
// fade out is supposed to only fade when there is a single row
|
||||
// however, some code might call hide() and show() directly after,
|
||||
// which results in more than one element
|
||||
// in this case, simply delete that one element that was supposed to
|
||||
// fade out
|
||||
//
|
||||
// FIXME: remove once all callers are adjusted to only hide their own notifications
|
||||
if ($notification.find('.row').length > 1) {
|
||||
$row.remove();
|
||||
return;
|
||||
// remove the row directly
|
||||
$row.each(function () {
|
||||
$(this)[0].toastify.hideToast()
|
||||
if (this === this.updatableNotification) {
|
||||
this.updatableNotification = null
|
||||
}
|
||||
|
||||
// else, fade out whatever was present
|
||||
$notification.fadeOut('400', function () {
|
||||
if (self.isHidden()) {
|
||||
if (self.getDefaultNotificationFunction) {
|
||||
self.getDefaultNotificationFunction.call();
|
||||
}
|
||||
}
|
||||
if (callback) {
|
||||
callback.call();
|
||||
}
|
||||
$notification.empty();
|
||||
});
|
||||
});
|
||||
})
|
||||
if (callback) {
|
||||
callback.call()
|
||||
}
|
||||
if (this.getDefaultNotificationFunction) {
|
||||
this.getDefaultNotificationFunction()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -116,45 +92,14 @@ export default {
|
|||
* @param {string} [options.type] notification type
|
||||
* @param {int} [options.timeout=0] timeout value, defaults to 0 (permanent)
|
||||
* @return {jQuery} jQuery element for notification row
|
||||
* @deprecated 17.0.0 use OCP.Toast
|
||||
*/
|
||||
showHtml: function (html, options) {
|
||||
options = options || {};
|
||||
_.defaults(options, {
|
||||
timeout: 0
|
||||
});
|
||||
|
||||
var self = this;
|
||||
var $notification = $('#notification');
|
||||
if (this.isHidden()) {
|
||||
$notification.fadeIn().css('display', 'inline-block');
|
||||
}
|
||||
var $row = $('<div class="row"></div>');
|
||||
if (options.type) {
|
||||
$row.addClass('type-' + options.type);
|
||||
}
|
||||
if (options.type === 'error') {
|
||||
// add a close button
|
||||
var $closeButton = $('<a class="action close icon-close" href="#"></a>');
|
||||
$closeButton.attr('alt', t('core', 'Dismiss'));
|
||||
$row.append($closeButton);
|
||||
$closeButton.one('click', function () {
|
||||
self.hide($row);
|
||||
return false;
|
||||
});
|
||||
$row.addClass('closeable');
|
||||
}
|
||||
|
||||
$row.prepend(html);
|
||||
$notification.append($row);
|
||||
|
||||
if (options.timeout > 0) {
|
||||
// register timeout to vanish notification
|
||||
this.notificationTimers.push(setTimeout(function () {
|
||||
self.hide($row);
|
||||
}, (options.timeout * 1000)));
|
||||
}
|
||||
|
||||
return $row;
|
||||
options = options || {}
|
||||
options.showHtml = true
|
||||
options.timeout = (options.timeout === 0) ? -1 : options.timeout
|
||||
const toast = window.OCP.Toast.message(html, options)
|
||||
return $(toast.toastElement)
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -165,9 +110,11 @@ export default {
|
|||
* @param {string} [options.type] notification type
|
||||
* @param {int} [options.timeout=0] timeout value, defaults to 0 (permanent)
|
||||
* @return {jQuery} jQuery element for notification row
|
||||
* @deprecated 17.0.0 use OCP.Toast
|
||||
*/
|
||||
show: function (text, options) {
|
||||
return this.showHtml($('<div/>').text(text).html(), options);
|
||||
const toast = window.OCP.Toast.message(text, options);
|
||||
return $(toast.toastElement);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -175,23 +122,14 @@ export default {
|
|||
*
|
||||
* @param {string} text Message to display
|
||||
* @return {jQuery} JQuery element for notificaiton row
|
||||
* @deprecated 17.0.0 use OCP.Toast
|
||||
*/
|
||||
showUpdate: function (text) {
|
||||
var $notification = $('#notification');
|
||||
// sanitise
|
||||
var $html = $('<div/>').text(text).html();
|
||||
|
||||
// new notification
|
||||
if (text && $notification.find('.row').length == 0) {
|
||||
return this.showHtml($html);
|
||||
if (this.updatableNotification) {
|
||||
this.updatableNotification.hideToast();
|
||||
}
|
||||
|
||||
var $row = $('<div class="row"></div>').prepend($html);
|
||||
|
||||
// just update html in notification
|
||||
$notification.html($row);
|
||||
|
||||
return $row;
|
||||
this.updatableNotification = OCP.Toast.message(text, {timeout: -1})
|
||||
return $(this.updatableNotification.toastElement);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -203,30 +141,21 @@ export default {
|
|||
* @param {int} [options.timeout=7] timeout in seconds, if this is 0 it will show the message permanently
|
||||
* @param {boolean} [options.isHTML=false] an indicator for HTML notifications (true) or text (false)
|
||||
* @param {string} [options.type] notification type
|
||||
* @deprecated 17.0.0 use OCP.Toast
|
||||
*/
|
||||
showTemporary: function (text, options) {
|
||||
var defaults = {
|
||||
isHTML: false,
|
||||
timeout: 7
|
||||
};
|
||||
options = options || {};
|
||||
// merge defaults with passed in options
|
||||
_.defaults(options, defaults);
|
||||
|
||||
var $row;
|
||||
if (options.isHTML) {
|
||||
$row = this.showHtml(text, options);
|
||||
} else {
|
||||
$row = this.show(text, options);
|
||||
}
|
||||
return $row;
|
||||
options = options || {}
|
||||
options.timeout = options.timeout || 7;
|
||||
const toast = window.OCP.Toast.message(text, options);
|
||||
return $(toast.toastElement);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether a notification is hidden.
|
||||
* @return {boolean}
|
||||
* @deprecated 17.0.0 use OCP.Toast
|
||||
*/
|
||||
isHidden: function () {
|
||||
return !$("#notification").find('.row').length;
|
||||
return !$('#content').find('.toastify').length;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,16 @@ import * as Comments from './comments'
|
|||
import * as InitialState from './initialstate'
|
||||
import Loader from './loader'
|
||||
import Collaboration from './collaboration'
|
||||
import Toast from './toast'
|
||||
import * as WhatsNew from './whatsnew'
|
||||
|
||||
/** @namespace OCP */
|
||||
export default {
|
||||
AppConfig,
|
||||
Collaboration,
|
||||
Comments,
|
||||
InitialState,
|
||||
Loader,
|
||||
WhatsNew,
|
||||
Collaboration
|
||||
Toast,
|
||||
WhatsNew
|
||||
};
|
||||
|
|
89
core/src/OCP/toast.js
Normal file
89
core/src/OCP/toast.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import Toastify from 'toastify-js'
|
||||
|
||||
const TOAST_TYPE_CLASES = {
|
||||
error: 'toast-error',
|
||||
info: 'toast-info',
|
||||
warning: 'toast-warning',
|
||||
success: 'toast-success',
|
||||
permanent: 'permanent'
|
||||
}
|
||||
|
||||
const Toast = {
|
||||
|
||||
success(text, options = {}) {
|
||||
options.type = 'success';
|
||||
return this.message(text, options)
|
||||
},
|
||||
|
||||
warning(text, options = {}) {
|
||||
options.type = 'warning';
|
||||
return this.message(text, options)
|
||||
},
|
||||
|
||||
error(text, options = {}) {
|
||||
options.type = 'error';
|
||||
return this.message(text, options)
|
||||
},
|
||||
|
||||
info(text, options = {}) {
|
||||
options.type = 'info';
|
||||
return this.message(text, options)
|
||||
},
|
||||
|
||||
message(text, options) {
|
||||
options = options || {};
|
||||
_.defaults(options, {
|
||||
timeout: 7,
|
||||
showHtml: false,
|
||||
type: undefined,
|
||||
close: true,
|
||||
callback: () => {}
|
||||
});
|
||||
if (!options.showHtml) {
|
||||
text = $('<div/>').text(text).html()
|
||||
}
|
||||
let classes = ''
|
||||
if (options.type) {
|
||||
classes = TOAST_TYPE_CLASES[options.type]
|
||||
}
|
||||
|
||||
const toast = Toastify({
|
||||
text: text,
|
||||
duration: options.timeout ? options.timeout*1000 : null,
|
||||
callback: options.callback,
|
||||
close: options.close,
|
||||
gravity: 'top',
|
||||
selector: 'content',
|
||||
positionLeft: false,
|
||||
backgroundColor: '',
|
||||
className: 'toast ' + classes
|
||||
})
|
||||
toast.showToast()
|
||||
// add toastify object to the element for reference in legacy OC.Notification
|
||||
toast.toastElement.toastify = toast;
|
||||
return toast
|
||||
}
|
||||
}
|
||||
export default Toast
|
54
package-lock.json
generated
54
package-lock.json
generated
|
@ -2330,6 +2330,34 @@
|
|||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true
|
||||
},
|
||||
"jsesc": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0="
|
||||
},
|
||||
"regexpu-core": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "http://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
|
||||
"integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
|
||||
"requires": {
|
||||
"regenerate": "^1.2.1",
|
||||
"regjsgen": "^0.2.0",
|
||||
"regjsparser": "^0.1.4"
|
||||
}
|
||||
},
|
||||
"regjsgen": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
|
||||
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc="
|
||||
},
|
||||
"regjsparser": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
|
||||
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
|
||||
"requires": {
|
||||
"jsesc": "~0.5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -3782,6 +3810,21 @@
|
|||
"optimist": "^0.6.1",
|
||||
"source-map": "^0.6.1",
|
||||
"uglify-js": "^3.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "http://registry.npmjs.org/async/-/async-2.6.1.tgz",
|
||||
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.10"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlebars-loader": {
|
||||
|
@ -4740,9 +4783,9 @@
|
|||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
||||
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
|
||||
"version": "0.0.8",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"mississippi": {
|
||||
"version": "3.0.0",
|
||||
|
@ -6950,6 +6993,11 @@
|
|||
"repeat-string": "^1.6.1"
|
||||
}
|
||||
},
|
||||
"toastify-js": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.5.0.tgz",
|
||||
"integrity": "sha512-tupU/X7DqwxYxTgT6n9SSEZLIGuwL1hFWg9uGQOzi8G04FLXoziw0GRF/TmuARrSQQCfIarfzoKEdDPG14Pr3Q=="
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
"query-string": "^5.1.1",
|
||||
"snap.js": "^2.0.9",
|
||||
"strengthify": "git+https://github.com/MorrisJobke/strengthify.git#0.5.8",
|
||||
"toastify-js": "^1.5.0",
|
||||
"underscore": "^1.9.1",
|
||||
"v-tooltip": "^2.0.2",
|
||||
"vue": "^2.6.10",
|
||||
|
|
Loading…
Reference in a new issue