mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-07 06:25:50 +01:00
added tinycon lib and changed notif icon to be in CSS instead of in
template
This commit is contained in:
@@ -66,7 +66,7 @@
|
|||||||
var notifContainer = document.getElementsByClassName('notifications')[0],
|
var notifContainer = document.getElementsByClassName('notifications')[0],
|
||||||
notifTrigger = notifContainer.querySelector('a'),
|
notifTrigger = notifContainer.querySelector('a'),
|
||||||
notifList = document.getElementById('notif-list'),
|
notifList = document.getElementById('notif-list'),
|
||||||
notifIcon = document.querySelector('.notifications a i');
|
notifIcon = $('.notifications a');
|
||||||
notifTrigger.addEventListener('click', function(e) {
|
notifTrigger.addEventListener('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (notifContainer.className.indexOf('open') === -1) {
|
if (notifContainer.className.indexOf('open') === -1) {
|
||||||
@@ -77,7 +77,6 @@
|
|||||||
numUnread = data.unread.length,
|
numUnread = data.unread.length,
|
||||||
x;
|
x;
|
||||||
notifList.innerHTML = '';
|
notifList.innerHTML = '';
|
||||||
console.log(data);
|
|
||||||
if ((data.read.length + data.unread.length) > 0) {
|
if ((data.read.length + data.unread.length) > 0) {
|
||||||
for (x = 0; x < numUnread; x++) {
|
for (x = 0; x < numUnread; x++) {
|
||||||
notifEl.setAttribute('data-nid', data.unread[x].nid);
|
notifEl.setAttribute('data-nid', data.unread[x].nid);
|
||||||
@@ -106,13 +105,13 @@
|
|||||||
notifList.appendChild(notifFrag);
|
notifList.appendChild(notifFrag);
|
||||||
|
|
||||||
if (data.unread.length > 0) {
|
if (data.unread.length > 0) {
|
||||||
notifIcon.className = 'fa fa-bell active';
|
notifIcon.toggleClass('active', true);
|
||||||
} else {
|
} else {
|
||||||
notifIcon.className = 'fa fa-bell-o';
|
notifIcon.toggleClass('active', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.emit('api:notifications.mark_all_read', null, function() {
|
socket.emit('api:notifications.mark_all_read', null, function() {
|
||||||
notifIcon.className = 'fa fa-bell-o';
|
notifIcon.toggleClass('active', false);
|
||||||
utils.refreshTitle();
|
utils.refreshTitle();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -138,8 +137,20 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.emit('api:notifications.getCount', function(count) {
|
||||||
|
// Update notification icon, if necessary
|
||||||
|
if (count > 0) {
|
||||||
|
notifIcon.toggleClass('active', true);
|
||||||
|
} else {
|
||||||
|
notifIcon.toggleClass('active', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update favicon
|
||||||
|
Tinycon.setBubble(count);
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('event:new_notification', function() {
|
socket.on('event:new_notification', function() {
|
||||||
document.querySelector('.notifications a i').className = 'fa fa-bell active';
|
notifIcon.toggleClass('active', true);
|
||||||
app.alert({
|
app.alert({
|
||||||
alert_id: 'new_notif',
|
alert_id: 'new_notif',
|
||||||
title: 'New notification',
|
title: 'New notification',
|
||||||
|
|||||||
@@ -90,7 +90,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li id="notifications-list" class="notifications dropdown text-center hidden-xs">
|
<li id="notifications-list" class="notifications dropdown text-center hidden-xs">
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#" id="notif_dropdown"><i class="fa fa-bell-o"></i></a>
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#" id="notif_dropdown"></a>
|
||||||
<ul id="notif-list" class="dropdown-menu" aria-labelledby="notif_dropdown">
|
<ul id="notif-list" class="dropdown-menu" aria-labelledby="notif_dropdown">
|
||||||
<li>
|
<li>
|
||||||
<a href="#"><i class="fa fa-refresh fa-spin"></i> [[global:notifications.loading]]</a>
|
<a href="#"><i class="fa fa-refresh fa-spin"></i> [[global:notifications.loading]]</a>
|
||||||
|
|||||||
267
public/vendor/tinycon/tinycon.js
vendored
Normal file
267
public/vendor/tinycon/tinycon.js
vendored
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
/*!
|
||||||
|
* Tinycon - A small library for manipulating the Favicon
|
||||||
|
* Tom Moor, http://tommoor.com
|
||||||
|
* Copyright (c) 2012 Tom Moor
|
||||||
|
* MIT Licensed
|
||||||
|
* @version 0.6.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var Tinycon = {};
|
||||||
|
var currentFavicon = null;
|
||||||
|
var originalFavicon = null;
|
||||||
|
var originalTitle = document.title;
|
||||||
|
var faviconImage = null;
|
||||||
|
var canvas = null;
|
||||||
|
var options = {};
|
||||||
|
var r = window.devicePixelRatio || 1;
|
||||||
|
var size = 16 * r;
|
||||||
|
var defaults = {
|
||||||
|
width: 7,
|
||||||
|
height: 9,
|
||||||
|
font: 10 * r + 'px arial',
|
||||||
|
colour: '#ffffff',
|
||||||
|
background: '#F03D25',
|
||||||
|
fallback: true,
|
||||||
|
crossOrigin: true,
|
||||||
|
abbreviate: true
|
||||||
|
};
|
||||||
|
|
||||||
|
var ua = (function () {
|
||||||
|
var agent = navigator.userAgent.toLowerCase();
|
||||||
|
// New function has access to 'agent' via closure
|
||||||
|
return function (browser) {
|
||||||
|
return agent.indexOf(browser) !== -1;
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
|
var browser = {
|
||||||
|
ie: ua('msie'),
|
||||||
|
chrome: ua('chrome'),
|
||||||
|
webkit: ua('chrome') || ua('safari'),
|
||||||
|
safari: ua('safari') && !ua('chrome'),
|
||||||
|
mozilla: ua('mozilla') && !ua('chrome') && !ua('safari')
|
||||||
|
};
|
||||||
|
|
||||||
|
// private methods
|
||||||
|
var getFaviconTag = function(){
|
||||||
|
|
||||||
|
var links = document.getElementsByTagName('link');
|
||||||
|
|
||||||
|
for(var i=0, len=links.length; i < len; i++) {
|
||||||
|
if ((links[i].getAttribute('rel') || '').match(/\bicon\b/)) {
|
||||||
|
return links[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
var removeFaviconTag = function(){
|
||||||
|
|
||||||
|
var links = document.getElementsByTagName('link');
|
||||||
|
var head = document.getElementsByTagName('head')[0];
|
||||||
|
|
||||||
|
for(var i=0, len=links.length; i < len; i++) {
|
||||||
|
var exists = (typeof(links[i]) !== 'undefined');
|
||||||
|
if (exists && (links[i].getAttribute('rel') || '').match(/\bicon\b/)) {
|
||||||
|
head.removeChild(links[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var getCurrentFavicon = function(){
|
||||||
|
|
||||||
|
if (!originalFavicon || !currentFavicon) {
|
||||||
|
var tag = getFaviconTag();
|
||||||
|
originalFavicon = currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico';
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentFavicon;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getCanvas = function (){
|
||||||
|
|
||||||
|
if (!canvas) {
|
||||||
|
canvas = document.createElement("canvas");
|
||||||
|
canvas.width = size;
|
||||||
|
canvas.height = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
};
|
||||||
|
|
||||||
|
var setFaviconTag = function(url){
|
||||||
|
removeFaviconTag();
|
||||||
|
|
||||||
|
var link = document.createElement('link');
|
||||||
|
link.type = 'image/x-icon';
|
||||||
|
link.rel = 'icon';
|
||||||
|
link.href = url;
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(link);
|
||||||
|
};
|
||||||
|
|
||||||
|
var log = function(message){
|
||||||
|
if (window.console) window.console.log(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawFavicon = function(label, colour) {
|
||||||
|
|
||||||
|
// fallback to updating the browser title if unsupported
|
||||||
|
if (!getCanvas().getContext || browser.ie || browser.safari || options.fallback === 'force') {
|
||||||
|
return updateTitle(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
var context = getCanvas().getContext("2d");
|
||||||
|
var colour = colour || '#000000';
|
||||||
|
var src = getCurrentFavicon();
|
||||||
|
|
||||||
|
faviconImage = document.createElement('img');
|
||||||
|
faviconImage.onload = function() {
|
||||||
|
|
||||||
|
// clear canvas
|
||||||
|
context.clearRect(0, 0, size, size);
|
||||||
|
|
||||||
|
// draw the favicon
|
||||||
|
context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size);
|
||||||
|
|
||||||
|
// draw bubble over the top
|
||||||
|
if ((label + '').length > 0) drawBubble(context, label, colour);
|
||||||
|
|
||||||
|
// refresh tag in page
|
||||||
|
refreshFavicon();
|
||||||
|
};
|
||||||
|
|
||||||
|
// allow cross origin resource requests if the image is not a data:uri
|
||||||
|
// as detailed here: https://github.com/mrdoob/three.js/issues/1305
|
||||||
|
if (!src.match(/^data/) && options.crossOrigin) {
|
||||||
|
faviconImage.crossOrigin = 'anonymous';
|
||||||
|
}
|
||||||
|
|
||||||
|
faviconImage.src = src;
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateTitle = function(label) {
|
||||||
|
|
||||||
|
if (options.fallback) {
|
||||||
|
if ((label + '').length > 0) {
|
||||||
|
document.title = '(' + label + ') ' + originalTitle;
|
||||||
|
} else {
|
||||||
|
document.title = originalTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var drawBubble = function(context, label, colour) {
|
||||||
|
|
||||||
|
// automatic abbreviation for long (>2 digits) numbers
|
||||||
|
if (typeof label == 'number' && label > 99 && options.abbreviate) {
|
||||||
|
label = abbreviateNumber(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bubble needs to be larger for double digits
|
||||||
|
var len = (label + '').length-1;
|
||||||
|
|
||||||
|
var width = options.width * r + (6 * r * len),
|
||||||
|
height = options.height * r;
|
||||||
|
|
||||||
|
var top = size - height,
|
||||||
|
left = size - width - r,
|
||||||
|
bottom = 16 * r,
|
||||||
|
right = 16 * r,
|
||||||
|
radius = 2 * r;
|
||||||
|
|
||||||
|
// webkit seems to render fonts lighter than firefox
|
||||||
|
context.font = (browser.webkit ? 'bold ' : '') + options.font;
|
||||||
|
context.fillStyle = options.background;
|
||||||
|
context.strokeStyle = options.background;
|
||||||
|
context.lineWidth = r;
|
||||||
|
|
||||||
|
// bubble
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(left + radius, top);
|
||||||
|
context.quadraticCurveTo(left, top, left, top + radius);
|
||||||
|
context.lineTo(left, bottom - radius);
|
||||||
|
context.quadraticCurveTo(left, bottom, left + radius, bottom);
|
||||||
|
context.lineTo(right - radius, bottom);
|
||||||
|
context.quadraticCurveTo(right, bottom, right, bottom - radius);
|
||||||
|
context.lineTo(right, top + radius);
|
||||||
|
context.quadraticCurveTo(right, top, right - radius, top);
|
||||||
|
context.closePath();
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// bottom shadow
|
||||||
|
context.beginPath();
|
||||||
|
context.strokeStyle = "rgba(0,0,0,0.3)";
|
||||||
|
context.moveTo(left + radius / 2.0, bottom);
|
||||||
|
context.lineTo(right - radius / 2.0, bottom);
|
||||||
|
context.stroke();
|
||||||
|
|
||||||
|
// label
|
||||||
|
context.fillStyle = options.colour;
|
||||||
|
context.textAlign = "right";
|
||||||
|
context.textBaseline = "top";
|
||||||
|
|
||||||
|
// unfortunately webkit/mozilla are a pixel different in text positioning
|
||||||
|
context.fillText(label, r === 2 ? 29 : 15, browser.mozilla ? 7*r : 6*r);
|
||||||
|
};
|
||||||
|
|
||||||
|
var refreshFavicon = function(){
|
||||||
|
// check support
|
||||||
|
if (!getCanvas().getContext) return;
|
||||||
|
|
||||||
|
setFaviconTag(getCanvas().toDataURL());
|
||||||
|
};
|
||||||
|
|
||||||
|
var abbreviateNumber = function(label) {
|
||||||
|
var metricPrefixes = [
|
||||||
|
['G', 1000000000],
|
||||||
|
['M', 1000000],
|
||||||
|
['k', 1000]
|
||||||
|
];
|
||||||
|
|
||||||
|
for(var i = 0; i < metricPrefixes.length; ++i) {
|
||||||
|
if (label >= metricPrefixes[i][1]) {
|
||||||
|
label = round(label / metricPrefixes[i][1]) + metricPrefixes[i][0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return label;
|
||||||
|
};
|
||||||
|
|
||||||
|
var round = function (value, precision) {
|
||||||
|
var number = new Number(value);
|
||||||
|
return number.toFixed(precision);
|
||||||
|
};
|
||||||
|
|
||||||
|
// public methods
|
||||||
|
Tinycon.setOptions = function(custom){
|
||||||
|
options = {};
|
||||||
|
|
||||||
|
for(var key in defaults){
|
||||||
|
options[key] = custom.hasOwnProperty(key) ? custom[key] : defaults[key];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tinycon.setImage = function(url){
|
||||||
|
currentFavicon = url;
|
||||||
|
refreshFavicon();
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tinycon.setBubble = function(label, colour) {
|
||||||
|
label = label || '';
|
||||||
|
drawFavicon(label, colour);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tinycon.reset = function(){
|
||||||
|
setFaviconTag(originalFavicon);
|
||||||
|
};
|
||||||
|
|
||||||
|
Tinycon.setOptions(defaults);
|
||||||
|
window.Tinycon = Tinycon;
|
||||||
|
})();
|
||||||
@@ -198,9 +198,10 @@ var utils = require('./../public/src/utils.js'),
|
|||||||
'vendor/jquery/js/jquery.timeago.js',
|
'vendor/jquery/js/jquery.timeago.js',
|
||||||
'vendor/jquery/js/jquery.form.js',
|
'vendor/jquery/js/jquery.form.js',
|
||||||
'vendor/bootstrap/js/bootstrap.min.js',
|
'vendor/bootstrap/js/bootstrap.min.js',
|
||||||
'src/app.js',
|
|
||||||
'vendor/requirejs/require.js',
|
'vendor/requirejs/require.js',
|
||||||
'vendor/bootbox/bootbox.min.js',
|
'vendor/bootbox/bootbox.min.js',
|
||||||
|
'vendor/tinycon/tinycon.js',
|
||||||
|
'src/app.js',
|
||||||
'src/templates.js',
|
'src/templates.js',
|
||||||
'src/ajaxify.js',
|
'src/ajaxify.js',
|
||||||
'src/translator.js',
|
'src/translator.js',
|
||||||
|
|||||||
Reference in New Issue
Block a user